1 /*
2  * Copyright 2016-2017 Józef Kucia for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18 
19 #ifdef _MSC_VER
20 /* Used for M_PI */
21 #define _USE_MATH_DEFINES
22 #endif
23 
24 #include "d3d12_crosstest.h"
25 
26 static PFN_D3D12_CREATE_VERSIONED_ROOT_SIGNATURE_DESERIALIZER pfn_D3D12CreateVersionedRootSignatureDeserializer;
27 static PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE pfn_D3D12SerializeVersionedRootSignature;
28 
29 struct vec2
30 {
31     float x, y;
32 };
33 
34 struct vec4
35 {
36     float x, y, z, w;
37 };
38 
39 struct uvec4
40 {
41     unsigned int x, y, z, w;
42 };
43 
44 struct ivec4
45 {
46     int x, y, z, w;
47 };
48 
compare_float(float f,float g,unsigned int ulps)49 static bool compare_float(float f, float g, unsigned int ulps)
50 {
51     int x, y;
52     union
53     {
54         float f;
55         int i;
56     } u;
57 
58     u.f = f;
59     x = u.i;
60     u.f = g;
61     y = u.i;
62 
63     if (x < 0)
64         x = INT_MIN - x;
65     if (y < 0)
66         y = INT_MIN - y;
67 
68     if (abs(x - y) > ulps)
69         return false;
70 
71     return true;
72 }
73 
compare_vec4(const struct vec4 * v1,const struct vec4 * v2,unsigned int ulps)74 static bool compare_vec4(const struct vec4 *v1, const struct vec4 *v2, unsigned int ulps)
75 {
76     return compare_float(v1->x, v2->x, ulps)
77             && compare_float(v1->y, v2->y, ulps)
78             && compare_float(v1->z, v2->z, ulps)
79             && compare_float(v1->w, v2->w, ulps);
80 }
81 
compare_uvec4(const struct uvec4 * v1,const struct uvec4 * v2)82 static bool compare_uvec4(const struct uvec4* v1, const struct uvec4 *v2)
83 {
84     return v1->x == v2->x && v1->y == v2->y && v1->z == v2->z && v1->w == v2->w;
85 }
86 
compare_uint8(uint8_t a,uint8_t b,unsigned int max_diff)87 static bool compare_uint8(uint8_t a, uint8_t b, unsigned int max_diff)
88 {
89     return abs(a - b) <= max_diff;
90 }
91 
compare_uint16(uint16_t a,uint16_t b,unsigned int max_diff)92 static bool compare_uint16(uint16_t a, uint16_t b, unsigned int max_diff)
93 {
94     return abs(a - b) <= max_diff;
95 }
96 
compare_uint64(uint64_t a,uint64_t b,unsigned int max_diff)97 static bool compare_uint64(uint64_t a, uint64_t b, unsigned int max_diff)
98 {
99     return llabs(a - b) <= max_diff;
100 }
101 
get_refcount(void * iface)102 static ULONG get_refcount(void *iface)
103 {
104     IUnknown *unk = iface;
105     IUnknown_AddRef(unk);
106     return IUnknown_Release(unk);
107 }
108 
109 #define check_interface(a, b, c) check_interface_(__LINE__, (IUnknown *)a, b, c)
check_interface_(unsigned int line,IUnknown * iface,REFIID riid,bool supported)110 static void check_interface_(unsigned int line, IUnknown *iface, REFIID riid, bool supported)
111 {
112     HRESULT hr, expected_hr;
113     IUnknown *unk;
114 
115     expected_hr = supported ? S_OK : E_NOINTERFACE;
116 
117     hr = IUnknown_QueryInterface(iface, riid, (void **)&unk);
118     ok_(line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
119     if (SUCCEEDED(hr))
120         IUnknown_Release(unk);
121 }
122 
123 #define check_heap_properties(a, b) check_heap_properties_(__LINE__, a, b)
check_heap_properties_(unsigned int line,const D3D12_HEAP_PROPERTIES * properties,const D3D12_HEAP_PROPERTIES * expected_properties)124 static void check_heap_properties_(unsigned int line,
125         const D3D12_HEAP_PROPERTIES *properties, const D3D12_HEAP_PROPERTIES *expected_properties)
126 {
127     D3D12_HEAP_PROPERTIES expected = *expected_properties;
128 
129     if (!expected.CreationNodeMask)
130         expected.CreationNodeMask = 0x1;
131     if (!expected.VisibleNodeMask)
132         expected.VisibleNodeMask = 0x1;
133 
134     ok_(line)(properties->Type == expected.Type,
135             "Got type %#x, expected %#x.\n", properties->Type, expected.Type);
136     ok_(line)(properties->CPUPageProperty == expected.CPUPageProperty,
137             "Got CPU page properties %#x, expected %#x.\n",
138             properties->CPUPageProperty, expected.CPUPageProperty);
139     ok_(line)(properties->MemoryPoolPreference == expected.MemoryPoolPreference,
140             "Got memory pool %#x, expected %#x.\n",
141             properties->MemoryPoolPreference, expected.MemoryPoolPreference);
142     ok_(line)(properties->CreationNodeMask == expected.CreationNodeMask,
143             "Got creation node mask %#x, expected %#x.\n",
144             properties->CreationNodeMask, expected.CreationNodeMask);
145     ok_(line)(properties->VisibleNodeMask == expected.VisibleNodeMask,
146             "Got visible node mask %#x, expected %#x.\n",
147             properties->VisibleNodeMask, expected.VisibleNodeMask);
148 }
149 
150 #define check_heap_desc(a, b) check_heap_desc_(__LINE__, a, b)
check_heap_desc_(unsigned int line,const D3D12_HEAP_DESC * desc,const D3D12_HEAP_DESC * expected_desc)151 static void check_heap_desc_(unsigned int line, const D3D12_HEAP_DESC *desc,
152         const D3D12_HEAP_DESC *expected_desc)
153 {
154     D3D12_HEAP_DESC expected = *expected_desc;
155 
156     if (!expected.Alignment)
157         expected.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
158 
159     ok_(line)(desc->SizeInBytes == expected.SizeInBytes,
160             "Got size %"PRIu64", expected %"PRIu64".\n",
161             desc->SizeInBytes, expected.SizeInBytes);
162     check_heap_properties_(line, &desc->Properties, &expected.Properties);
163     ok_(line)(desc->Alignment == expected.Alignment,
164             "Got alignment %"PRIu64", expected %"PRIu64".\n",
165             desc->Alignment, expected.Alignment);
166     ok_(line)(desc->Flags == expected.Flags,
167             "Got flags %#x, expected %#x.\n", desc->Flags, expected.Flags);
168 }
169 
170 #define check_alignment(a, b) check_alignment_(__LINE__, a, b)
check_alignment_(unsigned int line,uint64_t size,uint64_t alignment)171 static void check_alignment_(unsigned int line, uint64_t size, uint64_t alignment)
172 {
173     uint64_t aligned_size = align(size, alignment);
174     ok_(line)(aligned_size == size, "Got unaligned size %"PRIu64", expected %"PRIu64".\n",
175             size, aligned_size);
176 }
177 
uav_barrier(ID3D12GraphicsCommandList * list,ID3D12Resource * resource)178 static void uav_barrier(ID3D12GraphicsCommandList *list, ID3D12Resource *resource)
179 {
180     D3D12_RESOURCE_BARRIER barrier;
181 
182     barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
183     barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
184     barrier.UAV.pResource = resource;
185 
186     ID3D12GraphicsCommandList_ResourceBarrier(list, 1, &barrier);
187 }
188 
copy_sub_resource_data(const D3D12_MEMCPY_DEST * dst,const D3D12_SUBRESOURCE_DATA * src,unsigned int row_count,unsigned int slice_count,size_t row_size)189 static void copy_sub_resource_data(const D3D12_MEMCPY_DEST *dst, const D3D12_SUBRESOURCE_DATA *src,
190         unsigned int row_count, unsigned int slice_count, size_t row_size)
191 {
192     const BYTE *src_slice_ptr;
193     BYTE *dst_slice_ptr;
194     unsigned int z, y;
195 
196     for (z = 0; z < slice_count; ++z)
197     {
198         dst_slice_ptr = (BYTE *)dst->pData + z * dst->SlicePitch;
199         src_slice_ptr = (const BYTE*)src->pData + z * src->SlicePitch;
200         for (y = 0; y < row_count; ++y)
201             memcpy(dst_slice_ptr + y * dst->RowPitch, src_slice_ptr + y * src->RowPitch, row_size);
202     }
203 }
204 
205 #define upload_buffer_data(a, b, c, d, e, f) upload_buffer_data_(__LINE__, a, b, c, d, e, f)
upload_buffer_data_(unsigned int line,ID3D12Resource * buffer,size_t offset,size_t size,const void * data,ID3D12CommandQueue * queue,ID3D12GraphicsCommandList * command_list)206 static void upload_buffer_data_(unsigned int line, ID3D12Resource *buffer, size_t offset,
207         size_t size, const void *data, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list)
208 {
209     ID3D12Resource *upload_buffer;
210     ID3D12Device *device;
211     HRESULT hr;
212 
213     hr = ID3D12Resource_GetDevice(buffer, &IID_ID3D12Device, (void **)&device);
214     ok_(line)(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
215 
216     upload_buffer = create_upload_buffer_(line, device, size, data);
217 
218     ID3D12GraphicsCommandList_CopyBufferRegion(command_list, buffer, offset,
219             upload_buffer, 0, size);
220 
221     hr = ID3D12GraphicsCommandList_Close(command_list);
222     ok_(line)(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
223     exec_command_list(queue, command_list);
224     wait_queue_idle(device, queue);
225 
226     ID3D12Resource_Release(upload_buffer);
227     ID3D12Device_Release(device);
228 }
229 
230 #define upload_texture_data(a, b, c, d, e) upload_texture_data_(__LINE__, a, b, c, d, e)
upload_texture_data_(unsigned int line,ID3D12Resource * texture,const D3D12_SUBRESOURCE_DATA * data,unsigned int sub_resource_count,ID3D12CommandQueue * queue,ID3D12GraphicsCommandList * command_list)231 static void upload_texture_data_(unsigned int line, ID3D12Resource *texture,
232         const D3D12_SUBRESOURCE_DATA *data, unsigned int sub_resource_count,
233         ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list)
234 {
235     D3D12_TEXTURE_COPY_LOCATION dst_location, src_location;
236     D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts;
237     uint64_t *row_sizes, required_size;
238     D3D12_RESOURCE_DESC resource_desc;
239     ID3D12Resource *upload_buffer;
240     D3D12_MEMCPY_DEST dst_data;
241     ID3D12Device *device;
242     UINT *row_counts;
243     unsigned int i;
244     HRESULT hr;
245     void *ptr;
246 
247     layouts = calloc(sub_resource_count, sizeof(*layouts));
248     ok(layouts, "Failed to allocate memory.\n");
249     row_counts = calloc(sub_resource_count, sizeof(*row_counts));
250     ok(row_counts, "Failed to allocate memory.\n");
251     row_sizes = calloc(sub_resource_count, sizeof(*row_sizes));
252     ok(row_sizes, "Failed to allocate memory.\n");
253 
254     resource_desc = ID3D12Resource_GetDesc(texture);
255     hr = ID3D12Resource_GetDevice(texture, &IID_ID3D12Device, (void **)&device);
256     ok_(line)(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
257 
258     ID3D12Device_GetCopyableFootprints(device, &resource_desc, 0, sub_resource_count,
259             0, layouts, row_counts, row_sizes, &required_size);
260 
261     upload_buffer = create_upload_buffer_(line, device, required_size, NULL);
262 
263     hr = ID3D12Resource_Map(upload_buffer, 0, NULL, (void **)&ptr);
264     ok_(line)(SUCCEEDED(hr), "Failed to map upload buffer, hr %#x.\n", hr);
265     for (i = 0; i < sub_resource_count; ++i)
266     {
267         dst_data.pData = (BYTE *)ptr + layouts[i].Offset;
268         dst_data.RowPitch = layouts[i].Footprint.RowPitch;
269         dst_data.SlicePitch = layouts[i].Footprint.RowPitch * row_counts[i];
270         copy_sub_resource_data(&dst_data, &data[i],
271                 row_counts[i], layouts[i].Footprint.Depth, row_sizes[i]);
272     }
273     ID3D12Resource_Unmap(upload_buffer, 0, NULL);
274 
275     for (i = 0; i < sub_resource_count; ++i)
276     {
277         dst_location.pResource = texture;
278         dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
279         dst_location.SubresourceIndex = i;
280 
281         src_location.pResource = upload_buffer;
282         src_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
283         src_location.PlacedFootprint = layouts[i];
284 
285         ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
286                 &dst_location, 0, 0, 0, &src_location, NULL);
287     }
288 
289     hr = ID3D12GraphicsCommandList_Close(command_list);
290     ok_(line)(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
291 
292     exec_command_list(queue, command_list);
293     wait_queue_idle(device, queue);
294 
295     ID3D12Resource_Release(upload_buffer);
296     ID3D12Device_Release(device);
297 
298     free(layouts);
299     free(row_counts);
300     free(row_sizes);
301 }
302 
303 static const DXGI_FORMAT depth_stencil_formats[] =
304 {
305     DXGI_FORMAT_R32G8X24_TYPELESS,
306     DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
307     DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS,
308     DXGI_FORMAT_X32_TYPELESS_G8X24_UINT,
309     DXGI_FORMAT_R32_TYPELESS,
310     DXGI_FORMAT_D32_FLOAT,
311     DXGI_FORMAT_R24G8_TYPELESS,
312     DXGI_FORMAT_D24_UNORM_S8_UINT,
313     DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
314     DXGI_FORMAT_X24_TYPELESS_G8_UINT,
315     DXGI_FORMAT_R16_TYPELESS,
316     DXGI_FORMAT_D16_UNORM,
317 };
318 
init_readback(struct resource_readback * rb,ID3D12Resource * buffer,uint64_t buffer_size,uint64_t width,uint64_t height,unsigned int depth,uint64_t row_pitch)319 static void init_readback(struct resource_readback *rb, ID3D12Resource *buffer,
320         uint64_t buffer_size, uint64_t width, uint64_t height, unsigned int depth, uint64_t row_pitch)
321 {
322     D3D12_RANGE read_range;
323     HRESULT hr;
324 
325     rb->width = width;
326     rb->height = height;
327     rb->depth = depth;
328     rb->resource = buffer;
329     rb->row_pitch = row_pitch;
330     rb->data = NULL;
331 
332     ID3D12Resource_AddRef(rb->resource);
333 
334     read_range.Begin = 0;
335     read_range.End = buffer_size;
336     hr = ID3D12Resource_Map(rb->resource, 0, &read_range, &rb->data);
337     ok(hr == S_OK, "Failed to map readback buffer, hr %#x.\n", hr);
338 }
339 
get_buffer_readback_with_command_list(ID3D12Resource * buffer,DXGI_FORMAT format,struct resource_readback * rb,ID3D12CommandQueue * queue,ID3D12GraphicsCommandList * command_list)340 static void get_buffer_readback_with_command_list(ID3D12Resource *buffer, DXGI_FORMAT format,
341         struct resource_readback *rb, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list)
342 {
343     D3D12_HEAP_PROPERTIES heap_properties;
344     D3D12_RESOURCE_DESC resource_desc;
345     ID3D12Resource *rb_buffer;
346     D3D12_RANGE read_range;
347     ID3D12Device *device;
348     HRESULT hr;
349 
350     hr = ID3D12Resource_GetDevice(buffer, &IID_ID3D12Device, (void **)&device);
351     ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
352 
353     resource_desc = ID3D12Resource_GetDesc(buffer);
354     assert(resource_desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER);
355     resource_desc.Flags = D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
356 
357     hr = ID3D12Resource_GetHeapProperties(buffer, &heap_properties, NULL);
358     ok(SUCCEEDED(hr), "Failed to get heap properties.\n");
359     if (heap_properties.Type == D3D12_HEAP_TYPE_READBACK)
360     {
361         rb_buffer = buffer;
362         ID3D12Resource_AddRef(rb_buffer);
363     }
364     else
365     {
366         rb_buffer = create_readback_buffer(device, resource_desc.Width);
367         ID3D12GraphicsCommandList_CopyBufferRegion(command_list, rb_buffer, 0,
368                 buffer, 0, resource_desc.Width);
369     }
370 
371     hr = ID3D12GraphicsCommandList_Close(command_list);
372     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
373 
374     exec_command_list(queue, command_list);
375     wait_queue_idle(device, queue);
376     ID3D12Device_Release(device);
377 
378     rb->width = resource_desc.Width / format_size(format);
379     rb->height = 1;
380     rb->depth = 1;
381     rb->resource = rb_buffer;
382     rb->row_pitch = resource_desc.Width;
383     rb->data = NULL;
384 
385     read_range.Begin = 0;
386     read_range.End = resource_desc.Width;
387     hr = ID3D12Resource_Map(rb_buffer, 0, &read_range, &rb->data);
388     ok(SUCCEEDED(hr), "Failed to map readback buffer, hr %#x.\n", hr);
389 }
390 
get_readback_uint8(struct resource_readback * rb,unsigned int x,unsigned int y)391 static uint8_t get_readback_uint8(struct resource_readback *rb, unsigned int x, unsigned int y)
392 {
393     return *(uint8_t *)get_readback_data(rb, x, y, 0, sizeof(uint8_t));
394 }
395 
get_readback_uint16(struct resource_readback * rb,unsigned int x,unsigned int y)396 static uint16_t get_readback_uint16(struct resource_readback *rb, unsigned int x, unsigned int y)
397 {
398     return *(uint16_t *)get_readback_data(rb, x, y, 0, sizeof(uint16_t));
399 }
400 
get_readback_uint64(struct resource_readback * rb,unsigned int x,unsigned int y)401 static uint64_t get_readback_uint64(struct resource_readback *rb, unsigned int x, unsigned int y)
402 {
403     return *(uint64_t *)get_readback_data(rb, x, y, 0, sizeof(uint64_t));
404 }
405 
get_readback_float(struct resource_readback * rb,unsigned int x,unsigned int y)406 static float get_readback_float(struct resource_readback *rb, unsigned int x, unsigned int y)
407 {
408     return *(float *)get_readback_data(rb, x, y, 0, sizeof(float));
409 }
410 
get_readback_vec4(struct resource_readback * rb,unsigned int x,unsigned int y)411 static const struct vec4 *get_readback_vec4(struct resource_readback *rb, unsigned int x, unsigned int y)
412 {
413     return get_readback_data(rb, x, y, 0, sizeof(struct vec4));
414 }
415 
get_readback_uvec4(struct resource_readback * rb,unsigned int x,unsigned int y)416 static const struct uvec4 *get_readback_uvec4(struct resource_readback *rb, unsigned int x, unsigned int y)
417 {
418     return get_readback_data(rb, x, y, 0, sizeof(struct uvec4));
419 }
420 
421 #define check_readback_data_float(a, b, c, d) check_readback_data_float_(__LINE__, a, b, c, d)
check_readback_data_float_(unsigned int line,struct resource_readback * rb,const RECT * rect,float expected,unsigned int max_diff)422 static void check_readback_data_float_(unsigned int line, struct resource_readback *rb,
423         const RECT *rect, float expected, unsigned int max_diff)
424 {
425     RECT r = {0, 0, rb->width, rb->height};
426     unsigned int x = 0, y;
427     bool all_match = true;
428     float got = 0;
429 
430     if (rect)
431         r = *rect;
432 
433     for (y = r.top; y < r.bottom; ++y)
434     {
435         for (x = r.left; x < r.right; ++x)
436         {
437             got = get_readback_float(rb, x, y);
438             if (!compare_float(got, expected, max_diff))
439             {
440                 all_match = false;
441                 break;
442             }
443         }
444         if (!all_match)
445             break;
446     }
447     ok_(line)(all_match, "Got %.8e, expected %.8e at (%u, %u).\n", got, expected, x, y);
448 }
449 
450 #define check_sub_resource_float(a, b, c, d, e, f) check_sub_resource_float_(__LINE__, a, b, c, d, e, f)
check_sub_resource_float_(unsigned int line,ID3D12Resource * texture,unsigned int sub_resource_idx,ID3D12CommandQueue * queue,ID3D12GraphicsCommandList * command_list,float expected,unsigned int max_diff)451 static void check_sub_resource_float_(unsigned int line, ID3D12Resource *texture,
452         unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list,
453         float expected, unsigned int max_diff)
454 {
455     struct resource_readback rb;
456 
457     get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
458     check_readback_data_float_(line, &rb, NULL, expected, max_diff);
459     release_resource_readback(&rb);
460 }
461 
462 #define check_readback_data_uint8(a, b, c, d) check_readback_data_uint8_(__LINE__, a, b, c, d)
check_readback_data_uint8_(unsigned int line,struct resource_readback * rb,const RECT * rect,uint8_t expected,unsigned int max_diff)463 static void check_readback_data_uint8_(unsigned int line, struct resource_readback *rb,
464         const RECT *rect, uint8_t expected, unsigned int max_diff)
465 {
466     RECT r = {0, 0, rb->width, rb->height};
467     unsigned int x = 0, y;
468     bool all_match = true;
469     uint8_t got = 0;
470 
471     if (rect)
472         r = *rect;
473 
474     for (y = r.top; y < r.bottom; ++y)
475     {
476         for (x = r.left; x < r.right; ++x)
477         {
478             got = get_readback_uint8(rb, x, y);
479             if (!compare_uint8(got, expected, max_diff))
480             {
481                 all_match = false;
482                 break;
483             }
484         }
485         if (!all_match)
486             break;
487     }
488     ok_(line)(all_match, "Got 0x%02x, expected 0x%02x at (%u, %u).\n", got, expected, x, y);
489 }
490 
491 #define check_sub_resource_uint8(a, b, c, d, e, f) check_sub_resource_uint8_(__LINE__, a, b, c, d, e, f)
check_sub_resource_uint8_(unsigned int line,ID3D12Resource * texture,unsigned int sub_resource_idx,ID3D12CommandQueue * queue,ID3D12GraphicsCommandList * command_list,uint8_t expected,unsigned int max_diff)492 static void check_sub_resource_uint8_(unsigned int line, ID3D12Resource *texture,
493         unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list,
494         uint8_t expected, unsigned int max_diff)
495 {
496     struct resource_readback rb;
497 
498     get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
499     check_readback_data_uint8_(line, &rb, NULL, expected, max_diff);
500     release_resource_readback(&rb);
501 }
502 
503 #define check_readback_data_uint16(a, b, c, d) check_readback_data_uint16_(__LINE__, a, b, c, d)
check_readback_data_uint16_(unsigned int line,struct resource_readback * rb,const RECT * rect,uint16_t expected,unsigned int max_diff)504 static void check_readback_data_uint16_(unsigned int line, struct resource_readback *rb,
505         const RECT *rect, uint16_t expected, unsigned int max_diff)
506 {
507     RECT r = {0, 0, rb->width, rb->height};
508     unsigned int x = 0, y;
509     bool all_match = true;
510     uint16_t got = 0;
511 
512     if (rect)
513         r = *rect;
514 
515     for (y = r.top; y < r.bottom; ++y)
516     {
517         for (x = r.left; x < r.right; ++x)
518         {
519             got = get_readback_uint16(rb, x, y);
520             if (!compare_uint16(got, expected, max_diff))
521             {
522                 all_match = false;
523                 break;
524             }
525         }
526         if (!all_match)
527             break;
528     }
529     ok_(line)(all_match, "Got 0x%04x, expected 0x%04x at (%u, %u).\n", got, expected, x, y);
530 }
531 
532 #define check_sub_resource_uint16(a, b, c, d, e, f) check_sub_resource_uint16_(__LINE__, a, b, c, d, e, f)
check_sub_resource_uint16_(unsigned int line,ID3D12Resource * texture,unsigned int sub_resource_idx,ID3D12CommandQueue * queue,ID3D12GraphicsCommandList * command_list,uint16_t expected,unsigned int max_diff)533 static void check_sub_resource_uint16_(unsigned int line, ID3D12Resource *texture,
534         unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list,
535         uint16_t expected, unsigned int max_diff)
536 {
537     struct resource_readback rb;
538 
539     get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
540     check_readback_data_uint16_(line, &rb, NULL, expected, max_diff);
541     release_resource_readback(&rb);
542 }
543 
544 #define check_readback_data_uint64(a, b, c, d) check_readback_data_uint64_(__LINE__, a, b, c, d)
check_readback_data_uint64_(unsigned int line,struct resource_readback * rb,const RECT * rect,uint64_t expected,unsigned int max_diff)545 static void check_readback_data_uint64_(unsigned int line, struct resource_readback *rb,
546         const RECT *rect, uint64_t expected, unsigned int max_diff)
547 {
548     RECT r = {0, 0, rb->width, rb->height};
549     unsigned int x = 0, y;
550     bool all_match = true;
551     uint64_t got = 0;
552 
553     if (rect)
554         r = *rect;
555 
556     for (y = r.top; y < r.bottom; ++y)
557     {
558         for (x = r.left; x < r.right; ++x)
559         {
560             got = get_readback_uint64(rb, x, y);
561             if (!compare_uint64(got, expected, max_diff))
562             {
563                 all_match = false;
564                 break;
565             }
566         }
567         if (!all_match)
568             break;
569     }
570     ok_(line)(all_match, "Got %#"PRIx64", expected %#"PRIx64" at (%u, %u).\n", got, expected, x, y);
571 }
572 
573 #define check_sub_resource_uint64(a, b, c, d, e, f) check_sub_resource_uint64_(__LINE__, a, b, c, d, e, f)
check_sub_resource_uint64_(unsigned int line,ID3D12Resource * texture,unsigned int sub_resource_idx,ID3D12CommandQueue * queue,ID3D12GraphicsCommandList * command_list,uint64_t expected,unsigned int max_diff)574 static void check_sub_resource_uint64_(unsigned int line, ID3D12Resource *texture,
575         unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list,
576         uint64_t expected, unsigned int max_diff)
577 {
578     struct resource_readback rb;
579 
580     get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
581     check_readback_data_uint64_(line, &rb, NULL, expected, max_diff);
582     release_resource_readback(&rb);
583 }
584 
585 #define check_sub_resource_vec4(a, b, c, d, e, f) check_sub_resource_vec4_(__LINE__, a, b, c, d, e, f)
check_sub_resource_vec4_(unsigned int line,ID3D12Resource * texture,unsigned int sub_resource_idx,ID3D12CommandQueue * queue,ID3D12GraphicsCommandList * command_list,const struct vec4 * expected,unsigned int max_diff)586 static void check_sub_resource_vec4_(unsigned int line, ID3D12Resource *texture,
587         unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list,
588         const struct vec4 *expected, unsigned int max_diff)
589 {
590     struct resource_readback rb;
591     unsigned int x = 0, y;
592     bool all_match = true;
593     struct vec4 got = {0};
594 
595     get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
596     for (y = 0; y < rb.height; ++y)
597     {
598         for (x = 0; x < rb.width; ++x)
599         {
600             got = *get_readback_vec4(&rb, x, y);
601             if (!compare_vec4(&got, expected, max_diff))
602             {
603                 all_match = false;
604                 break;
605             }
606         }
607         if (!all_match)
608             break;
609     }
610     release_resource_readback(&rb);
611 
612     ok_(line)(all_match, "Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e} at (%u, %u).\n",
613             got.x, got.y, got.z, got.w, expected->x, expected->y, expected->z, expected->w, x, y);
614 }
615 
616 #define check_sub_resource_uvec4(a, b, c, d, e) check_sub_resource_uvec4_(__LINE__, a, b, c, d, e)
check_sub_resource_uvec4_(unsigned int line,ID3D12Resource * texture,unsigned int sub_resource_idx,ID3D12CommandQueue * queue,ID3D12GraphicsCommandList * command_list,const struct uvec4 * expected_value)617 static void check_sub_resource_uvec4_(unsigned int line, ID3D12Resource *texture,
618         unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list,
619         const struct uvec4 *expected_value)
620 {
621     struct resource_readback rb;
622     struct uvec4 value = {0};
623     unsigned int x = 0, y;
624     bool all_match = true;
625 
626     get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
627     for (y = 0; y < rb.height; ++y)
628     {
629         for (x = 0; x < rb.width; ++x)
630         {
631             value = *get_readback_uvec4(&rb, x, y);
632             if (!compare_uvec4(&value, expected_value))
633             {
634                 all_match = false;
635                 break;
636             }
637         }
638         if (!all_match)
639             break;
640     }
641     release_resource_readback(&rb);
642 
643     ok_(line)(all_match,
644             "Got {0x%08x, 0x%08x, 0x%08x, 0x%08x}, expected {0x%08x, 0x%08x, 0x%08x, 0x%08x} at (%u, %u).\n",
645             value.x, value.y, value.z, value.w,
646             expected_value->x, expected_value->y, expected_value->z, expected_value->w, x, y);
647 }
648 
649 #define check_buffer_uint(a, b, c, d, e) check_buffer_uint_(__LINE__, a, b, c, d, e)
check_buffer_uint_(unsigned int line,ID3D12Resource * buffer,ID3D12CommandQueue * queue,ID3D12GraphicsCommandList * command_list,unsigned int expected,unsigned int max_diff)650 static void check_buffer_uint_(unsigned int line, ID3D12Resource *buffer,
651         ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list,
652         unsigned int expected, unsigned int max_diff)
653 {
654     struct resource_readback rb;
655 
656     get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
657     check_readback_data_uint_(line, &rb, NULL, expected, max_diff);
658     release_resource_readback(&rb);
659 }
660 
broken_on_warp(bool condition)661 static bool broken_on_warp(bool condition)
662 {
663     return broken(use_warp_device && condition);
664 }
665 
is_min_max_filtering_supported(ID3D12Device * device)666 static bool is_min_max_filtering_supported(ID3D12Device *device)
667 {
668     D3D12_FEATURE_DATA_D3D12_OPTIONS options;
669     HRESULT hr;
670 
671     if (FAILED(hr = ID3D12Device_CheckFeatureSupport(device,
672             D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options))))
673     {
674         trace("Failed to check feature support, hr %#x.\n", hr);
675         return false;
676     }
677 
678     /* D3D12 validation layer says tiled resource tier 2+ support implies min/max filtering support. */
679     return options.TiledResourcesTier >= D3D12_TILED_RESOURCES_TIER_2;
680 }
681 
get_tiled_resources_tier(ID3D12Device * device)682 static D3D12_TILED_RESOURCES_TIER get_tiled_resources_tier(ID3D12Device *device)
683 {
684     D3D12_FEATURE_DATA_D3D12_OPTIONS options;
685     HRESULT hr;
686 
687     if (FAILED(hr = ID3D12Device_CheckFeatureSupport(device,
688             D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options))))
689     {
690         trace("Failed to check feature support, hr %#x.\n", hr);
691         return D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED;
692     }
693 
694     return options.TiledResourcesTier;
695 }
696 
is_standard_swizzle_64kb_supported(ID3D12Device * device)697 static bool is_standard_swizzle_64kb_supported(ID3D12Device *device)
698 {
699     D3D12_FEATURE_DATA_D3D12_OPTIONS options;
700     HRESULT hr;
701 
702     if (FAILED(hr = ID3D12Device_CheckFeatureSupport(device,
703             D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options))))
704     {
705         trace("Failed to check feature support, hr %#x.\n", hr);
706         return false;
707     }
708 
709     return options.StandardSwizzle64KBSupported;
710 }
711 
is_memory_pool_L1_supported(ID3D12Device * device)712 static bool is_memory_pool_L1_supported(ID3D12Device *device)
713 {
714     D3D12_FEATURE_DATA_ARCHITECTURE architecture;
715     HRESULT hr;
716 
717     memset(&architecture, 0, sizeof(architecture));
718     if (FAILED(hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_ARCHITECTURE,
719             &architecture, sizeof(architecture))))
720     {
721         trace("Failed to check feature support, hr %#x.\n", hr);
722         return false;
723     }
724 
725     return !architecture.UMA;
726 }
727 
728 #define create_cb_root_signature(a, b, c, e) create_cb_root_signature_(__LINE__, a, b, c, e)
create_cb_root_signature_(unsigned int line,ID3D12Device * device,unsigned int reg_idx,D3D12_SHADER_VISIBILITY shader_visibility,D3D12_ROOT_SIGNATURE_FLAGS flags)729 static ID3D12RootSignature *create_cb_root_signature_(unsigned int line,
730         ID3D12Device *device, unsigned int reg_idx, D3D12_SHADER_VISIBILITY shader_visibility,
731         D3D12_ROOT_SIGNATURE_FLAGS flags)
732 {
733     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
734     ID3D12RootSignature *root_signature = NULL;
735     D3D12_ROOT_PARAMETER root_parameter;
736     HRESULT hr;
737 
738     root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
739     root_parameter.Descriptor.ShaderRegister = reg_idx;
740     root_parameter.Descriptor.RegisterSpace = 0;
741     root_parameter.ShaderVisibility = shader_visibility;
742 
743     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
744     root_signature_desc.NumParameters = 1;
745     root_signature_desc.pParameters = &root_parameter;
746     root_signature_desc.Flags = flags;
747     hr = create_root_signature(device, &root_signature_desc, &root_signature);
748     ok_(line)(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
749 
750     return root_signature;
751 }
752 
753 #define create_32bit_constants_root_signature(a, b, c, e) \
754         create_32bit_constants_root_signature_(__LINE__, a, b, c, e, 0)
create_32bit_constants_root_signature_(unsigned int line,ID3D12Device * device,unsigned int reg_idx,unsigned int element_count,D3D12_SHADER_VISIBILITY shader_visibility,D3D12_ROOT_SIGNATURE_FLAGS flags)755 static ID3D12RootSignature *create_32bit_constants_root_signature_(unsigned int line,
756         ID3D12Device *device, unsigned int reg_idx, unsigned int element_count,
757         D3D12_SHADER_VISIBILITY shader_visibility, D3D12_ROOT_SIGNATURE_FLAGS flags)
758 {
759     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
760     ID3D12RootSignature *root_signature = NULL;
761     D3D12_ROOT_PARAMETER root_parameter;
762     HRESULT hr;
763 
764     root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
765     root_parameter.Constants.ShaderRegister = reg_idx;
766     root_parameter.Constants.RegisterSpace = 0;
767     root_parameter.Constants.Num32BitValues = element_count;
768     root_parameter.ShaderVisibility = shader_visibility;
769 
770     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
771     root_signature_desc.NumParameters = 1;
772     root_signature_desc.pParameters = &root_parameter;
773     root_signature_desc.Flags = flags;
774     hr = create_root_signature(device, &root_signature_desc, &root_signature);
775     ok_(line)(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
776 
777     return root_signature;
778 }
779 
780 #define create_texture_root_signature(a, b, c, d) create_texture_root_signature_(__LINE__, a, b, c, d, NULL)
create_texture_root_signature_(unsigned int line,ID3D12Device * device,D3D12_SHADER_VISIBILITY shader_visibility,unsigned int constant_count,D3D12_ROOT_SIGNATURE_FLAGS flags,const D3D12_STATIC_SAMPLER_DESC * sampler_desc)781 static ID3D12RootSignature *create_texture_root_signature_(unsigned int line,
782         ID3D12Device *device, D3D12_SHADER_VISIBILITY shader_visibility,
783         unsigned int constant_count, D3D12_ROOT_SIGNATURE_FLAGS flags,
784         const D3D12_STATIC_SAMPLER_DESC *sampler_desc)
785 {
786     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
787     ID3D12RootSignature *root_signature = NULL;
788     D3D12_STATIC_SAMPLER_DESC static_sampler;
789     D3D12_DESCRIPTOR_RANGE descriptor_range;
790     D3D12_ROOT_PARAMETER root_parameters[2];
791     HRESULT hr;
792 
793     if (sampler_desc)
794     {
795         static_sampler = *sampler_desc;
796     }
797     else
798     {
799         memset(&static_sampler, 0, sizeof(static_sampler));
800         static_sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
801         static_sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
802         static_sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
803         static_sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
804         static_sampler.MaxLOD = D3D12_FLOAT32_MAX;
805         static_sampler.ShaderRegister = 0;
806         static_sampler.RegisterSpace = 0;
807         static_sampler.ShaderVisibility = shader_visibility;
808     }
809 
810     descriptor_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
811     descriptor_range.NumDescriptors = 1;
812     descriptor_range.BaseShaderRegister = 0;
813     descriptor_range.RegisterSpace = 0;
814     descriptor_range.OffsetInDescriptorsFromTableStart = 0;
815     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
816     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
817     root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_range;
818     root_parameters[0].ShaderVisibility = shader_visibility;
819 
820     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
821     root_parameters[1].Constants.ShaderRegister = 0;
822     root_parameters[1].Constants.RegisterSpace = 0;
823     root_parameters[1].Constants.Num32BitValues = constant_count;
824     root_parameters[1].ShaderVisibility = shader_visibility;
825 
826     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
827     root_signature_desc.NumParameters = constant_count ? 2 : 1;
828     root_signature_desc.pParameters = root_parameters;
829     root_signature_desc.NumStaticSamplers = 1;
830     root_signature_desc.pStaticSamplers = &static_sampler;
831     root_signature_desc.Flags = flags;
832 
833     hr = create_root_signature(device, &root_signature_desc, &root_signature);
834     ok_(line)(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
835 
836     return root_signature;
837 }
838 
839 #define create_compute_pipeline_state(a, b, c) create_compute_pipeline_state_(__LINE__, a, b, c)
create_compute_pipeline_state_(unsigned int line,ID3D12Device * device,ID3D12RootSignature * root_signature,const D3D12_SHADER_BYTECODE cs)840 static ID3D12PipelineState *create_compute_pipeline_state_(unsigned int line, ID3D12Device *device,
841         ID3D12RootSignature *root_signature, const D3D12_SHADER_BYTECODE cs)
842 {
843     D3D12_COMPUTE_PIPELINE_STATE_DESC pipeline_state_desc;
844     ID3D12PipelineState *pipeline_state;
845     HRESULT hr;
846 
847     memset(&pipeline_state_desc, 0, sizeof(pipeline_state_desc));
848     pipeline_state_desc.pRootSignature = root_signature;
849     pipeline_state_desc.CS = cs;
850     pipeline_state_desc.NodeMask = 0;
851     pipeline_state_desc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
852     hr = ID3D12Device_CreateComputePipelineState(device, &pipeline_state_desc,
853             &IID_ID3D12PipelineState, (void **)&pipeline_state);
854     ok_(line)(SUCCEEDED(hr), "Failed to create compute pipeline state, hr %#x.\n", hr);
855 
856     return pipeline_state;
857 }
858 
859 #define create_command_signature(a, b) create_command_signature_(__LINE__, a, b)
create_command_signature_(unsigned int line,ID3D12Device * device,D3D12_INDIRECT_ARGUMENT_TYPE argument_type)860 static ID3D12CommandSignature *create_command_signature_(unsigned int line,
861         ID3D12Device *device, D3D12_INDIRECT_ARGUMENT_TYPE argument_type)
862 {
863     D3D12_COMMAND_SIGNATURE_DESC signature_desc;
864     D3D12_INDIRECT_ARGUMENT_DESC argument_desc;
865     ID3D12CommandSignature *command_signature;
866     HRESULT hr;
867 
868     argument_desc.Type = argument_type;
869 
870     switch (argument_type)
871     {
872         case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW:
873             signature_desc.ByteStride = sizeof(D3D12_DRAW_ARGUMENTS);
874             break;
875         case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED:
876             signature_desc.ByteStride = sizeof(D3D12_DRAW_INDEXED_ARGUMENTS);
877             break;
878         case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH:
879             signature_desc.ByteStride = sizeof(D3D12_DISPATCH_ARGUMENTS);
880             break;
881         default:
882             return NULL;
883     }
884 
885     signature_desc.NumArgumentDescs = 1;
886     signature_desc.pArgumentDescs = &argument_desc;
887     signature_desc.NodeMask = 0;
888     hr = ID3D12Device_CreateCommandSignature(device, &signature_desc,
889             NULL, &IID_ID3D12CommandSignature, (void **)&command_signature);
890     ok_(line)(hr == S_OK, "Failed to create command signature, hr %#x.\n", hr);
891 
892     return command_signature;
893 }
894 
895 #define init_compute_test_context(context) init_compute_test_context_(__LINE__, context)
init_compute_test_context_(unsigned int line,struct test_context * context)896 static bool init_compute_test_context_(unsigned int line, struct test_context *context)
897 {
898     ID3D12Device *device;
899     HRESULT hr;
900 
901     memset(context, 0, sizeof(*context));
902 
903     if (!(context->device = create_device()))
904     {
905         skip_(line)("Failed to create device.\n");
906         return false;
907     }
908     device = context->device;
909 
910     context->queue = create_command_queue_(line, device,
911             D3D12_COMMAND_LIST_TYPE_COMPUTE, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
912 
913     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_COMPUTE,
914             &IID_ID3D12CommandAllocator, (void **)&context->allocator);
915     ok_(line)(hr == S_OK, "Failed to create command allocator, hr %#x.\n", hr);
916 
917     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_COMPUTE,
918             context->allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&context->list);
919     ok_(line)(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
920 
921     return true;
922 }
923 
924 struct depth_stencil_resource
925 {
926     ID3D12Resource *texture;
927     ID3D12DescriptorHeap *heap;
928     D3D12_CPU_DESCRIPTOR_HANDLE dsv_handle;
929 };
930 
931 #define init_depth_stencil(a, b, c, d, e, f, g, h, i) init_depth_stencil_(__LINE__, a, b, c, d, e, f, g, h, i)
init_depth_stencil_(unsigned int line,struct depth_stencil_resource * ds,ID3D12Device * device,unsigned int width,unsigned int height,unsigned int array_size,unsigned int level_count,DXGI_FORMAT format,DXGI_FORMAT view_format,const D3D12_CLEAR_VALUE * clear_value)932 static void init_depth_stencil_(unsigned int line, struct depth_stencil_resource *ds,
933         ID3D12Device *device, unsigned int width, unsigned int height, unsigned int array_size, unsigned int level_count,
934         DXGI_FORMAT format, DXGI_FORMAT view_format, const D3D12_CLEAR_VALUE *clear_value)
935 {
936     D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc, *view_desc;
937     D3D12_HEAP_PROPERTIES heap_properties;
938     D3D12_RESOURCE_DESC resource_desc;
939     HRESULT hr;
940 
941     memset(ds, 0, sizeof(*ds));
942 
943     ds->heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1);
944 
945     memset(&heap_properties, 0, sizeof(heap_properties));
946     heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
947     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
948     resource_desc.Alignment = 0;
949     resource_desc.Width = width;
950     resource_desc.Height = height;
951     resource_desc.DepthOrArraySize = array_size;
952     resource_desc.MipLevels = level_count;
953     resource_desc.Format = format;
954     resource_desc.SampleDesc.Count = 1;
955     resource_desc.SampleDesc.Quality = 0;
956     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
957     resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
958     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
959             &resource_desc, D3D12_RESOURCE_STATE_DEPTH_WRITE, clear_value,
960             &IID_ID3D12Resource, (void **)&ds->texture);
961     ok_(line)(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
962 
963     view_desc = NULL;
964     if (view_format)
965     {
966         memset(&dsv_desc, 0, sizeof(dsv_desc));
967         dsv_desc.Format = view_format;
968         dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
969         view_desc = &dsv_desc;
970     }
971     ds->dsv_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(ds->heap);
972     ID3D12Device_CreateDepthStencilView(device, ds->texture, view_desc, ds->dsv_handle);
973 }
974 
975 #define destroy_depth_stencil(depth_stencil) destroy_depth_stencil_(__LINE__, depth_stencil)
destroy_depth_stencil_(unsigned int line,struct depth_stencil_resource * ds)976 static void destroy_depth_stencil_(unsigned int line, struct depth_stencil_resource *ds)
977 {
978     ID3D12DescriptorHeap_Release(ds->heap);
979     ID3D12Resource_Release(ds->texture);
980 }
981 
test_create_device(void)982 static void test_create_device(void)
983 {
984     ID3D12Device *device;
985     ULONG refcount;
986     HRESULT hr;
987 
988     if (!(device = create_device()))
989     {
990         skip("Failed to create device.\n");
991         return;
992     }
993 
994     check_interface(device, &IID_ID3D12Object, true);
995     check_interface(device, &IID_ID3D12DeviceChild, false);
996     check_interface(device, &IID_ID3D12Pageable, false);
997     check_interface(device, &IID_ID3D12Device, true);
998 
999     refcount = ID3D12Device_Release(device);
1000     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
1001 
1002     hr = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, (void **)&device);
1003     ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr);
1004     ID3D12Device_Release(device);
1005 
1006     hr = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, NULL);
1007     ok(hr == S_FALSE, "Got unexpected hr %#x.\n", hr);
1008     hr = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, NULL, NULL);
1009     ok(hr == S_FALSE, "Got unexpected hr %#x.\n", hr);
1010     hr = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12DeviceChild, NULL);
1011     ok(hr == S_FALSE, "Got unexpected hr %#x.\n", hr);
1012 
1013     hr = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_9_1, &IID_ID3D12Device, (void **)&device);
1014     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1015     hr = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_9_2, &IID_ID3D12Device, (void **)&device);
1016     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1017     hr = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_9_3, &IID_ID3D12Device, (void **)&device);
1018     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1019     hr = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_10_0, &IID_ID3D12Device, (void **)&device);
1020     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1021     hr = D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_10_1, &IID_ID3D12Device, (void **)&device);
1022     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1023 
1024     hr = D3D12CreateDevice(NULL, 0, &IID_ID3D12Device, (void **)&device);
1025     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1026     hr = D3D12CreateDevice(NULL, ~0u, &IID_ID3D12Device, (void **)&device);
1027     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1028 }
1029 
test_node_count(void)1030 static void test_node_count(void)
1031 {
1032     ID3D12Device *device;
1033     UINT node_count;
1034     ULONG refcount;
1035 
1036     if (!(device = create_device()))
1037     {
1038         skip("Failed to create device.\n");
1039         return;
1040     }
1041 
1042     node_count = ID3D12Device_GetNodeCount(device);
1043     trace("Node count: %u.\n", node_count);
1044     ok(1 <= node_count && node_count <= 32, "Got unexpected node count %u.\n", node_count);
1045 
1046     refcount = ID3D12Device_Release(device);
1047     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
1048 }
1049 
test_check_feature_support(void)1050 static void test_check_feature_support(void)
1051 {
1052     D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT gpu_virtual_address;
1053     D3D12_FEATURE_DATA_FEATURE_LEVELS feature_levels;
1054     D3D12_FEATURE_DATA_ROOT_SIGNATURE root_signature;
1055     D3D_FEATURE_LEVEL max_supported_feature_level;
1056     D3D12_FEATURE_DATA_ARCHITECTURE architecture;
1057     D3D12_FEATURE_DATA_FORMAT_INFO format_info;
1058     unsigned int expected_plane_count;
1059     ID3D12Device *device;
1060     DXGI_FORMAT format;
1061     ULONG refcount;
1062     bool is_todo;
1063     HRESULT hr;
1064 
1065     static const D3D_FEATURE_LEVEL all_feature_levels[] =
1066     {
1067         D3D_FEATURE_LEVEL_12_1,
1068         D3D_FEATURE_LEVEL_12_0,
1069         D3D_FEATURE_LEVEL_11_1,
1070         D3D_FEATURE_LEVEL_11_0,
1071         D3D_FEATURE_LEVEL_10_1,
1072         D3D_FEATURE_LEVEL_10_0,
1073         D3D_FEATURE_LEVEL_9_3,
1074         D3D_FEATURE_LEVEL_9_2,
1075         D3D_FEATURE_LEVEL_9_1,
1076     };
1077     static const D3D_FEATURE_LEVEL d3d12_feature_levels[] =
1078     {
1079         D3D_FEATURE_LEVEL_12_1,
1080         D3D_FEATURE_LEVEL_12_0,
1081         D3D_FEATURE_LEVEL_11_1,
1082         D3D_FEATURE_LEVEL_11_0,
1083     };
1084     static const D3D_FEATURE_LEVEL d3d_9_x_feature_levels[] =
1085     {
1086         D3D_FEATURE_LEVEL_9_3,
1087         D3D_FEATURE_LEVEL_9_2,
1088         D3D_FEATURE_LEVEL_9_1,
1089     };
1090     static const D3D_FEATURE_LEVEL invalid_feature_levels[] =
1091     {
1092         0x0000,
1093         0x3000,
1094     };
1095 
1096     if (!(device = create_device()))
1097     {
1098         skip("Failed to create device.\n");
1099         return;
1100     }
1101 
1102     /* Architecture. */
1103     memset(&architecture, 0, sizeof(architecture));
1104     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_ARCHITECTURE,
1105             &architecture, sizeof(architecture));
1106     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1107     ok(!architecture.NodeIndex, "Got unexpected node %u.\n", architecture.NodeIndex);
1108     ok(!architecture.CacheCoherentUMA || architecture.UMA,
1109             "Got unexpected cache coherent UMA %#x (UMA %#x).\n",
1110             architecture.CacheCoherentUMA, architecture.UMA);
1111     trace("UMA %#x, cache coherent UMA %#x, tile based renderer %#x.\n",
1112             architecture.UMA, architecture.CacheCoherentUMA, architecture.TileBasedRenderer);
1113 
1114     if (ID3D12Device_GetNodeCount(device) == 1)
1115     {
1116         memset(&architecture, 0, sizeof(architecture));
1117         architecture.NodeIndex = 1;
1118         hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_ARCHITECTURE,
1119                 &architecture, sizeof(architecture));
1120         ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1121     }
1122 
1123     /* Feature levels */
1124     memset(&feature_levels, 0, sizeof(feature_levels));
1125     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_FEATURE_LEVELS,
1126             &feature_levels, sizeof(feature_levels));
1127     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1128 
1129     feature_levels.NumFeatureLevels = ARRAY_SIZE(all_feature_levels);
1130     feature_levels.pFeatureLevelsRequested = all_feature_levels;
1131     feature_levels.MaxSupportedFeatureLevel = 0;
1132     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_FEATURE_LEVELS,
1133             &feature_levels, sizeof(feature_levels));
1134     ok(hr == S_OK, "Failed to check feature support, hr %#x.\n", hr);
1135     trace("Max supported feature level %#x.\n", feature_levels.MaxSupportedFeatureLevel);
1136     max_supported_feature_level = feature_levels.MaxSupportedFeatureLevel;
1137 
1138     feature_levels.NumFeatureLevels = ARRAY_SIZE(d3d12_feature_levels);
1139     feature_levels.pFeatureLevelsRequested = d3d12_feature_levels;
1140     feature_levels.MaxSupportedFeatureLevel = 0;
1141     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_FEATURE_LEVELS,
1142             &feature_levels, sizeof(feature_levels));
1143     ok(hr == S_OK, "Failed to check feature support, hr %#x.\n", hr);
1144     ok(feature_levels.MaxSupportedFeatureLevel == max_supported_feature_level,
1145             "Got unexpected feature level %#x, expected %#x.\n",
1146             feature_levels.MaxSupportedFeatureLevel, max_supported_feature_level);
1147 
1148     /* Check invalid size. */
1149     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_FEATURE_LEVELS,
1150             &feature_levels, sizeof(feature_levels) + 1);
1151     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1152     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_FEATURE_LEVELS,
1153             &feature_levels, sizeof(feature_levels) - 1);
1154     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1155 
1156     feature_levels.NumFeatureLevels = ARRAY_SIZE(d3d_9_x_feature_levels);
1157     feature_levels.pFeatureLevelsRequested = d3d_9_x_feature_levels;
1158     feature_levels.MaxSupportedFeatureLevel = 0;
1159     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_FEATURE_LEVELS,
1160             &feature_levels, sizeof(feature_levels));
1161     ok(hr == S_OK, "Failed to check feature support, hr %#x.\n", hr);
1162     ok(feature_levels.MaxSupportedFeatureLevel == D3D_FEATURE_LEVEL_9_3,
1163             "Got unexpected max feature level %#x.\n", feature_levels.MaxSupportedFeatureLevel);
1164 
1165     feature_levels.NumFeatureLevels = ARRAY_SIZE(invalid_feature_levels);
1166     feature_levels.pFeatureLevelsRequested = invalid_feature_levels;
1167     feature_levels.MaxSupportedFeatureLevel = 0;
1168     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_FEATURE_LEVELS,
1169             &feature_levels, sizeof(feature_levels));
1170     ok(hr == S_OK, "Failed to check feature support, hr %#x.\n", hr);
1171     ok(feature_levels.MaxSupportedFeatureLevel == 0x3000,
1172             "Got unexpected max feature level %#x.\n", feature_levels.MaxSupportedFeatureLevel);
1173 
1174     /* Format info. */
1175     memset(&format_info, 0, sizeof(format_info));
1176     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_FORMAT_INFO,
1177             &format_info, sizeof(format_info));
1178     ok(hr == S_OK, "Failed to get format info, hr %#x.\n", hr);
1179     ok(format_info.Format == DXGI_FORMAT_UNKNOWN, "Got unexpected format %#x.\n", format_info.Format);
1180     ok(format_info.PlaneCount == 1, "Got unexpected plane count %u.\n", format_info.PlaneCount);
1181 
1182     for (format = DXGI_FORMAT_UNKNOWN; format <= DXGI_FORMAT_B4G4R4A4_UNORM; ++format)
1183     {
1184         vkd3d_test_set_context("format %#x", format);
1185 
1186         switch (format)
1187         {
1188             case DXGI_FORMAT_R32G8X24_TYPELESS:
1189             case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
1190             case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
1191             case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
1192             case DXGI_FORMAT_D24_UNORM_S8_UINT:
1193             case DXGI_FORMAT_R24G8_TYPELESS:
1194             case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
1195             case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
1196             case DXGI_FORMAT_NV12:
1197             case DXGI_FORMAT_P010:
1198             case DXGI_FORMAT_P016:
1199             case DXGI_FORMAT_NV11:
1200                 expected_plane_count = 2;
1201                 break;
1202             default:
1203                 expected_plane_count = 1;
1204                 break;
1205         }
1206 
1207         is_todo = format == DXGI_FORMAT_R9G9B9E5_SHAREDEXP
1208                 || format == DXGI_FORMAT_R8G8_B8G8_UNORM
1209                 || format == DXGI_FORMAT_G8R8_G8B8_UNORM
1210                 || format == DXGI_FORMAT_B5G6R5_UNORM
1211                 || format == DXGI_FORMAT_B5G5R5A1_UNORM
1212                 || format == DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM
1213                 || (DXGI_FORMAT_AYUV <= format && format <= DXGI_FORMAT_B4G4R4A4_UNORM);
1214 
1215         memset(&format_info, 0, sizeof(format_info));
1216         format_info.Format = format;
1217         hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_FORMAT_INFO,
1218                 &format_info, sizeof(format_info));
1219 
1220         if (format == DXGI_FORMAT_R1_UNORM)
1221         {
1222             ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1223             continue;
1224         }
1225 
1226         todo_if(is_todo)
1227         ok(hr == S_OK, "Failed to get format info, hr %#x.\n", hr);
1228         ok(format_info.Format == format, "Got unexpected format %#x.\n", format_info.Format);
1229         todo_if(is_todo)
1230         ok(format_info.PlaneCount == expected_plane_count,
1231                 "Got plane count %u, expected %u.\n", format_info.PlaneCount, expected_plane_count);
1232     }
1233     vkd3d_test_set_context(NULL);
1234 
1235     /* GPU virtual address */
1236     memset(&gpu_virtual_address, 0, sizeof(gpu_virtual_address));
1237     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT,
1238             &gpu_virtual_address, sizeof(gpu_virtual_address));
1239     ok(hr == S_OK, "Failed to check GPU virtual address support, hr %#x.\n", hr);
1240     trace("GPU virtual address bits per resource: %u.\n",
1241             gpu_virtual_address.MaxGPUVirtualAddressBitsPerResource);
1242     trace("GPU virtual address bits per process: %u.\n",
1243             gpu_virtual_address.MaxGPUVirtualAddressBitsPerProcess);
1244 
1245     root_signature.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0;
1246     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_ROOT_SIGNATURE,
1247             &root_signature, sizeof(root_signature));
1248     ok(hr == S_OK, "Failed to get root signature feature support, hr %#x.\n", hr);
1249     ok(root_signature.HighestVersion == D3D_ROOT_SIGNATURE_VERSION_1_0,
1250             "Got unexpected root signature feature version %#x.\n", root_signature.HighestVersion);
1251 
1252     root_signature.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1;
1253     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_ROOT_SIGNATURE,
1254             &root_signature, sizeof(root_signature));
1255     ok(hr == S_OK, "Failed to get root signature feature support, hr %#x.\n", hr);
1256     ok(root_signature.HighestVersion == D3D_ROOT_SIGNATURE_VERSION_1_0
1257             || root_signature.HighestVersion == D3D_ROOT_SIGNATURE_VERSION_1_1,
1258             "Got unexpected root signature feature version %#x.\n", root_signature.HighestVersion);
1259 
1260     refcount = ID3D12Device_Release(device);
1261     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
1262 }
1263 
test_format_support(void)1264 static void test_format_support(void)
1265 {
1266     D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support;
1267     ID3D12Device *device;
1268     ULONG refcount;
1269     unsigned int i;
1270     HRESULT hr;
1271 
1272     static const struct
1273     {
1274         D3D12_FEATURE_DATA_FORMAT_SUPPORT f;
1275         bool broken;
1276     }
1277     unsupported_format_features[] =
1278     {
1279         /* A recent version of WARP suppots B8G8R8A8 UAVs even on D3D_FEATURE_LEVEL_11_0. */
1280         {{DXGI_FORMAT_B8G8R8A8_TYPELESS, D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW,
1281                 D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD | D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE}, true},
1282     };
1283 
1284     if (!(device = create_device()))
1285     {
1286         skip("Failed to create device.\n");
1287         return;
1288     }
1289 
1290     memset(&format_support, 0, sizeof(format_support));
1291     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_FORMAT_SUPPORT,
1292             &format_support, sizeof(format_support));
1293     todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1294     todo ok(format_support.Support1 == D3D12_FORMAT_SUPPORT1_BUFFER,
1295             "Got unexpected support1 %#x.\n", format_support.Support1);
1296     ok(!format_support.Support2 || format_support.Support2 == D3D12_FORMAT_SUPPORT2_TILED,
1297             "Got unexpected support2 %#x.\n", format_support.Support2);
1298 
1299     for (i = 0; i < ARRAY_SIZE(unsupported_format_features); ++i)
1300     {
1301         memset(&format_support, 0, sizeof(format_support));
1302         format_support.Format = unsupported_format_features[i].f.Format;
1303         hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_FORMAT_SUPPORT,
1304                 &format_support, sizeof(format_support));
1305         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1306         ok(!(format_support.Support1 & unsupported_format_features[i].f.Support1)
1307                 || broken_on_warp(unsupported_format_features[i].broken),
1308                 "Format %#x supports %#x.\n", unsupported_format_features[i].f.Format,
1309                 format_support.Support1 & unsupported_format_features[i].f.Support1);
1310         ok(!(format_support.Support2 & unsupported_format_features[i].f.Support2)
1311                 || broken_on_warp(unsupported_format_features[i].broken),
1312                 "Format %#x supports %#x.\n", unsupported_format_features[i].f.Format,
1313                 format_support.Support2 & unsupported_format_features[i].f.Support2);
1314     }
1315 
1316     for (i = 0; i < ARRAY_SIZE(depth_stencil_formats); ++i)
1317     {
1318         memset(&format_support, 0, sizeof(format_support));
1319         format_support.Format = depth_stencil_formats[i];
1320         hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_FORMAT_SUPPORT,
1321                 &format_support, sizeof(format_support));
1322         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1323     }
1324 
1325     refcount = ID3D12Device_Release(device);
1326     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
1327 }
1328 
test_multisample_quality_levels(void)1329 static void test_multisample_quality_levels(void)
1330 {
1331     static const unsigned int sample_counts[] = {1, 2, 4, 8, 16, 32};
1332     D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS format_support;
1333     ID3D12Device *device;
1334     DXGI_FORMAT format;
1335     unsigned int i, j;
1336     ULONG refcount;
1337     HRESULT hr;
1338 
1339     if (!(device = create_device()))
1340     {
1341         skip("Failed to create device.\n");
1342         return;
1343     }
1344 
1345     memset(&format_support, 0, sizeof(format_support));
1346     format_support.NumQualityLevels = 0xdeadbeef;
1347     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
1348             &format_support, sizeof(format_support));
1349     ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
1350     ok(!format_support.Flags, "Got unexpected flags %#x.\n", format_support.Flags);
1351     ok(!format_support.NumQualityLevels, "Got unexpected quality levels %u.\n", format_support.NumQualityLevels);
1352 
1353     format_support.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
1354     format_support.NumQualityLevels = 0xdeadbeef;
1355     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
1356             &format_support, sizeof(format_support));
1357     ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
1358     ok(!format_support.Flags, "Got unexpected flags %#x.\n", format_support.Flags);
1359     ok(!format_support.NumQualityLevels, "Got unexpected quality levels %u.\n", format_support.NumQualityLevels);
1360 
1361     /* 1 sample */
1362     for (format = DXGI_FORMAT_UNKNOWN; format <= DXGI_FORMAT_B4G4R4A4_UNORM; ++format)
1363     {
1364         if (format == DXGI_FORMAT_R1_UNORM)
1365             continue;
1366 
1367         vkd3d_test_set_context("format %#x", format);
1368 
1369         memset(&format_support, 0, sizeof(format_support));
1370         format_support.Format = format;
1371         format_support.SampleCount = 1;
1372         format_support.NumQualityLevels = 0xdeadbeef;
1373         hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
1374                 &format_support, sizeof(format_support));
1375         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1376         ok(format_support.NumQualityLevels == 1, "Got unexpected quality levels %u.\n", format_support.NumQualityLevels);
1377     }
1378     vkd3d_test_set_context(NULL);
1379 
1380     /* DXGI_FORMAT_UNKNOWN */
1381     for (i = 1; i < ARRAY_SIZE(sample_counts); ++i)
1382     {
1383         vkd3d_test_set_context("samples %#x", sample_counts[i]);
1384 
1385         memset(&format_support, 0, sizeof(format_support));
1386         format_support.SampleCount = sample_counts[i];
1387         format_support.NumQualityLevels = 0xdeadbeef;
1388         hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
1389                 &format_support, sizeof(format_support));
1390         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1391         ok(!format_support.Flags, "Got unexpected flags %#x.\n", format_support.Flags);
1392         ok(!format_support.NumQualityLevels, "Got unexpected quality levels %u.\n", format_support.NumQualityLevels);
1393 
1394         format_support.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE;
1395         format_support.NumQualityLevels = 0xdeadbeef;
1396         hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
1397                 &format_support, sizeof(format_support));
1398         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1399         ok(format_support.Flags == D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE,
1400                 "Got unexpected flags %#x.\n", format_support.Flags);
1401         ok(!format_support.NumQualityLevels, "Got unexpected quality levels %u.\n", format_support.NumQualityLevels);
1402     }
1403     vkd3d_test_set_context(NULL);
1404 
1405     /* invalid sample counts */
1406     for (i = 1; i <= 32; ++i)
1407     {
1408         bool valid_sample_count = false;
1409         for (j = 0; j < ARRAY_SIZE(sample_counts); ++j)
1410         {
1411             if (sample_counts[j] == i)
1412             {
1413                 valid_sample_count = true;
1414                 break;
1415             }
1416         }
1417         if (valid_sample_count)
1418             continue;
1419 
1420         vkd3d_test_set_context("samples %#x", i);
1421 
1422         memset(&format_support, 0, sizeof(format_support));
1423         format_support.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
1424         format_support.SampleCount = i;
1425         format_support.NumQualityLevels = 0xdeadbeef;
1426         hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
1427                 &format_support, sizeof(format_support));
1428         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1429         ok(!format_support.Flags, "Got unexpected flags %#x.\n", format_support.Flags);
1430         ok(!format_support.NumQualityLevels, "Got unexpected quality levels %u.\n", format_support.NumQualityLevels);
1431     }
1432     vkd3d_test_set_context(NULL);
1433 
1434     /* DXGI_FORMAT_R8G8B8A8_UNORM */
1435     memset(&format_support, 0, sizeof(format_support));
1436     format_support.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
1437     format_support.SampleCount = 4;
1438     format_support.NumQualityLevels = 0xdeadbeef;
1439     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
1440             &format_support, sizeof(format_support));
1441     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1442     ok(!format_support.Flags, "Got unexpected flags %#x.\n", format_support.Flags);
1443     ok(format_support.NumQualityLevels >= 1, "Got unexpected quality levels %u.\n", format_support.NumQualityLevels);
1444 
1445     for (i = 0; i < ARRAY_SIZE(depth_stencil_formats); ++i)
1446     {
1447         memset(&format_support, 0, sizeof(format_support));
1448         format_support.Format = depth_stencil_formats[i];
1449         format_support.SampleCount = 4;
1450         format_support.NumQualityLevels = 0xdeadbeef;
1451         hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
1452                 &format_support, sizeof(format_support));
1453         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
1454     }
1455 
1456     refcount = ID3D12Device_Release(device);
1457     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
1458 }
1459 
test_create_command_allocator(void)1460 static void test_create_command_allocator(void)
1461 {
1462     ID3D12CommandAllocator *command_allocator;
1463     ID3D12Device *device, *tmp_device;
1464     ULONG refcount;
1465     HRESULT hr;
1466 
1467     if (!(device = create_device()))
1468     {
1469         skip("Failed to create device.\n");
1470         return;
1471     }
1472 
1473     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
1474             &IID_ID3D12CommandAllocator, (void **)&command_allocator);
1475     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
1476 
1477     refcount = get_refcount(device);
1478     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1479     hr = ID3D12CommandAllocator_GetDevice(command_allocator, &IID_ID3D12Device, (void **)&tmp_device);
1480     ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
1481     refcount = get_refcount(device);
1482     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1483     refcount = ID3D12Device_Release(tmp_device);
1484     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1485 
1486     check_interface(command_allocator, &IID_ID3D12Object, true);
1487     check_interface(command_allocator, &IID_ID3D12DeviceChild, true);
1488     check_interface(command_allocator, &IID_ID3D12Pageable, true);
1489     check_interface(command_allocator, &IID_ID3D12CommandAllocator, true);
1490 
1491     refcount = ID3D12CommandAllocator_Release(command_allocator);
1492     ok(!refcount, "ID3D12CommandAllocator has %u references left.\n", (unsigned int)refcount);
1493 
1494     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_BUNDLE,
1495             &IID_ID3D12CommandAllocator, (void **)&command_allocator);
1496     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
1497     refcount = ID3D12CommandAllocator_Release(command_allocator);
1498     ok(!refcount, "ID3D12CommandAllocator has %u references left.\n", (unsigned int)refcount);
1499 
1500     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_COMPUTE,
1501             &IID_ID3D12CommandAllocator, (void **)&command_allocator);
1502     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
1503     refcount = ID3D12CommandAllocator_Release(command_allocator);
1504     ok(!refcount, "ID3D12CommandAllocator has %u references left.\n", (unsigned int)refcount);
1505 
1506     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_COPY,
1507             &IID_ID3D12CommandAllocator, (void **)&command_allocator);
1508     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
1509     refcount = ID3D12CommandAllocator_Release(command_allocator);
1510     ok(!refcount, "ID3D12CommandAllocator has %u references left.\n", (unsigned int)refcount);
1511 
1512     hr = ID3D12Device_CreateCommandAllocator(device, ~0u,
1513             &IID_ID3D12CommandAllocator, (void **)&command_allocator);
1514     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1515 
1516     refcount = ID3D12Device_Release(device);
1517     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
1518 }
1519 
test_create_command_list(void)1520 static void test_create_command_list(void)
1521 {
1522     ID3D12CommandAllocator *command_allocator;
1523     ID3D12Device *device, *tmp_device;
1524     ID3D12CommandList *command_list;
1525     ULONG refcount;
1526     HRESULT hr;
1527 
1528     if (!(device = create_device()))
1529     {
1530         skip("Failed to create device.\n");
1531         return;
1532     }
1533 
1534     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
1535             NULL, NULL, &IID_ID3D12CommandList, (void **)&command_list);
1536     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1537 
1538     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
1539             &IID_ID3D12CommandAllocator, (void **)&command_allocator);
1540     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
1541 
1542     refcount = get_refcount(device);
1543     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1544 
1545     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
1546             command_allocator, NULL, &IID_ID3D12CommandList, (void **)&command_list);
1547     ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
1548 
1549     refcount = get_refcount(command_allocator);
1550     ok(refcount == 1, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1551 
1552     refcount = get_refcount(device);
1553     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1554     hr = ID3D12CommandList_GetDevice(command_list, &IID_ID3D12Device, (void **)&tmp_device);
1555     ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
1556     refcount = get_refcount(device);
1557     ok(refcount == 4, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1558     refcount = ID3D12Device_Release(tmp_device);
1559     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1560 
1561     check_interface(command_list, &IID_ID3D12Object, true);
1562     check_interface(command_list, &IID_ID3D12DeviceChild, true);
1563     check_interface(command_list, &IID_ID3D12Pageable, false);
1564     check_interface(command_list, &IID_ID3D12CommandList, true);
1565     check_interface(command_list, &IID_ID3D12GraphicsCommandList, true);
1566     check_interface(command_list, &IID_ID3D12CommandAllocator, false);
1567 
1568     refcount = ID3D12CommandList_Release(command_list);
1569     ok(!refcount, "ID3D12CommandList has %u references left.\n", (unsigned int)refcount);
1570     refcount = ID3D12CommandAllocator_Release(command_allocator);
1571     ok(!refcount, "ID3D12CommandAllocator has %u references left.\n", (unsigned int)refcount);
1572 
1573     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_BUNDLE,
1574             &IID_ID3D12CommandAllocator, (void **)&command_allocator);
1575     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
1576     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
1577             command_allocator, NULL, &IID_ID3D12CommandList, (void **)&command_list);
1578     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1579     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_BUNDLE,
1580             command_allocator, NULL, &IID_ID3D12CommandList, (void **)&command_list);
1581     ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
1582     check_interface(command_list, &IID_ID3D12GraphicsCommandList, true);
1583     refcount = ID3D12CommandList_Release(command_list);
1584     ok(!refcount, "ID3D12CommandList has %u references left.\n", (unsigned int)refcount);
1585     refcount = ID3D12CommandAllocator_Release(command_allocator);
1586     ok(!refcount, "ID3D12CommandAllocator has %u references left.\n", (unsigned int)refcount);
1587 
1588     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_COMPUTE,
1589             &IID_ID3D12CommandAllocator, (void **)&command_allocator);
1590     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
1591     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_BUNDLE,
1592             command_allocator, NULL, &IID_ID3D12CommandList, (void **)&command_list);
1593     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1594     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_COMPUTE,
1595             command_allocator, NULL, &IID_ID3D12CommandList, (void **)&command_list);
1596     ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
1597     check_interface(command_list, &IID_ID3D12GraphicsCommandList, true);
1598     refcount = ID3D12CommandList_Release(command_list);
1599     ok(!refcount, "ID3D12CommandList has %u references left.\n", (unsigned int)refcount);
1600     refcount = ID3D12CommandAllocator_Release(command_allocator);
1601     ok(!refcount, "ID3D12CommandAllocator has %u references left.\n", (unsigned int)refcount);
1602 
1603     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_COPY,
1604             &IID_ID3D12CommandAllocator, (void **)&command_allocator);
1605     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
1606     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
1607             command_allocator, NULL, &IID_ID3D12CommandList, (void **)&command_list);
1608     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1609     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_COMPUTE,
1610             command_allocator, NULL, &IID_ID3D12CommandList, (void **)&command_list);
1611     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1612     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_COPY,
1613             command_allocator, NULL, &IID_ID3D12CommandList, (void **)&command_list);
1614     ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
1615     check_interface(command_list, &IID_ID3D12GraphicsCommandList, true);
1616     refcount = ID3D12CommandList_Release(command_list);
1617     ok(!refcount, "ID3D12CommandList has %u references left.\n", (unsigned int)refcount);
1618     refcount = ID3D12CommandAllocator_Release(command_allocator);
1619     ok(!refcount, "ID3D12CommandAllocator has %u references left.\n", (unsigned int)refcount);
1620 
1621     refcount = ID3D12Device_Release(device);
1622     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
1623 }
1624 
test_create_command_queue(void)1625 static void test_create_command_queue(void)
1626 {
1627     ID3D12CommandQueue* direct_queues[32], *compute_queues[32];
1628     D3D12_COMMAND_QUEUE_DESC desc, result_desc;
1629     ID3D12Device *device, *tmp_device;
1630     ID3D12CommandQueue *queue;
1631     unsigned int i;
1632     ULONG refcount;
1633     HRESULT hr;
1634 
1635     if (!(device = create_device()))
1636     {
1637         skip("Failed to create device.\n");
1638         return;
1639     }
1640 
1641     desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
1642     desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
1643     desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
1644     desc.NodeMask = 0;
1645     hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&queue);
1646     ok(SUCCEEDED(hr), "Failed to create command queue, hr %#x.\n", hr);
1647 
1648     refcount = get_refcount(device);
1649     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1650     hr = ID3D12CommandQueue_GetDevice(queue, &IID_ID3D12Device, (void **)&tmp_device);
1651     ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
1652     refcount = get_refcount(device);
1653     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1654     refcount = ID3D12Device_Release(tmp_device);
1655     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1656 
1657     check_interface(queue, &IID_ID3D12Object, true);
1658     check_interface(queue, &IID_ID3D12DeviceChild, true);
1659     check_interface(queue, &IID_ID3D12Pageable, true);
1660     check_interface(queue, &IID_ID3D12CommandQueue, true);
1661 
1662     result_desc = ID3D12CommandQueue_GetDesc(queue);
1663     ok(result_desc.Type == desc.Type, "Got unexpected type %#x.\n", result_desc.Type);
1664     ok(result_desc.Priority == desc.Priority, "Got unexpected priority %#x.\n", result_desc.Priority);
1665     ok(result_desc.Flags == desc.Flags, "Got unexpected flags %#x.\n", result_desc.Flags);
1666     ok(result_desc.NodeMask == 0x1, "Got unexpected node mask 0x%08x.\n", result_desc.NodeMask);
1667 
1668     refcount = ID3D12CommandQueue_Release(queue);
1669     ok(!refcount, "ID3D12CommandQueue has %u references left.\n", (unsigned int)refcount);
1670 
1671     desc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE;
1672     hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&queue);
1673     ok(SUCCEEDED(hr), "Failed to create command queue, hr %#x.\n", hr);
1674 
1675     result_desc = ID3D12CommandQueue_GetDesc(queue);
1676     ok(result_desc.Type == desc.Type, "Got unexpected type %#x.\n", result_desc.Type);
1677     ok(result_desc.Priority == desc.Priority, "Got unexpected priority %#x.\n", result_desc.Priority);
1678     ok(result_desc.Flags == desc.Flags, "Got unexpected flags %#x.\n", result_desc.Flags);
1679     ok(result_desc.NodeMask == 0x1, "Got unexpected node mask 0x%08x.\n", result_desc.NodeMask);
1680 
1681     refcount = ID3D12CommandQueue_Release(queue);
1682     ok(!refcount, "ID3D12CommandQueue has %u references left.\n", (unsigned int)refcount);
1683 
1684     desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
1685     for (i = 0; i < ARRAY_SIZE(direct_queues); ++i)
1686     {
1687         hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&direct_queues[i]);
1688         ok(hr == S_OK, "Failed to create direct command queue %u, hr %#x.\n", hr, i);
1689     }
1690     desc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE;
1691     for (i = 0; i < ARRAY_SIZE(compute_queues); ++i)
1692     {
1693         hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&compute_queues[i]);
1694         ok(hr == S_OK, "Failed to create compute command queue %u, hr %#x.\n", hr, i);
1695     }
1696 
1697     for (i = 0; i < ARRAY_SIZE(direct_queues); ++i)
1698         ID3D12CommandQueue_Release(direct_queues[i]);
1699     for (i = 0; i < ARRAY_SIZE(compute_queues); ++i)
1700         ID3D12CommandQueue_Release(compute_queues[i]);
1701 
1702     refcount = ID3D12Device_Release(device);
1703     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
1704 }
1705 
test_create_command_signature(void)1706 static void test_create_command_signature(void)
1707 {
1708     D3D12_INDIRECT_ARGUMENT_DESC argument_desc[3];
1709     D3D12_COMMAND_SIGNATURE_DESC signature_desc;
1710     ID3D12CommandSignature *command_signature;
1711     ID3D12Device *device;
1712     unsigned int i;
1713     ULONG refcount;
1714     HRESULT hr;
1715 
1716     if (!(device = create_device()))
1717     {
1718         skip("Failed to create device.\n");
1719         return;
1720     }
1721 
1722     signature_desc.ByteStride = 1024;
1723     signature_desc.NumArgumentDescs = ARRAY_SIZE(argument_desc);
1724     signature_desc.pArgumentDescs = argument_desc;
1725     signature_desc.NodeMask = 0;
1726 
1727     for (i = 0; i < ARRAY_SIZE(argument_desc); ++i)
1728         argument_desc[i].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW;
1729     hr = ID3D12Device_CreateCommandSignature(device, &signature_desc,
1730             NULL, &IID_ID3D12CommandSignature, (void **)&command_signature);
1731     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1732 
1733     for (i = 0; i < ARRAY_SIZE(argument_desc); ++i)
1734         argument_desc[i].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;
1735     hr = ID3D12Device_CreateCommandSignature(device, &signature_desc,
1736             NULL, &IID_ID3D12CommandSignature, (void **)&command_signature);
1737     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1738 
1739     for (i = 0; i < ARRAY_SIZE(argument_desc); ++i)
1740         argument_desc[i].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH;
1741     hr = ID3D12Device_CreateCommandSignature(device, &signature_desc,
1742             NULL, &IID_ID3D12CommandSignature, (void **)&command_signature);
1743     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1744 
1745     argument_desc[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH;
1746     argument_desc[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW;
1747     signature_desc.NumArgumentDescs = 2;
1748     hr = ID3D12Device_CreateCommandSignature(device, &signature_desc,
1749             NULL, &IID_ID3D12CommandSignature, (void **)&command_signature);
1750     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1751 
1752     refcount = ID3D12Device_Release(device);
1753     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
1754 }
1755 
test_create_committed_resource(void)1756 static void test_create_committed_resource(void)
1757 {
1758     D3D12_GPU_VIRTUAL_ADDRESS gpu_address;
1759     D3D12_HEAP_PROPERTIES heap_properties;
1760     D3D12_RESOURCE_DESC resource_desc;
1761     ID3D12Device *device, *tmp_device;
1762     D3D12_CLEAR_VALUE clear_value;
1763     D3D12_RESOURCE_STATES state;
1764     ID3D12Resource *resource;
1765     unsigned int i;
1766     ULONG refcount;
1767     HRESULT hr;
1768 
1769     static const struct
1770     {
1771         D3D12_HEAP_TYPE heap_type;
1772         D3D12_RESOURCE_FLAGS flags;
1773     }
1774     invalid_buffer_desc_tests[] =
1775     {
1776         /* Render target or unordered access resources are not allowed with UPLOAD or READBACK. */
1777         {D3D12_HEAP_TYPE_UPLOAD,   D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET},
1778         {D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET},
1779         {D3D12_HEAP_TYPE_UPLOAD,   D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS},
1780         {D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS},
1781         {D3D12_HEAP_TYPE_DEFAULT,  D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS},
1782         {D3D12_HEAP_TYPE_UPLOAD,   D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS},
1783         {D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS},
1784     };
1785 
1786     if (!(device = create_device()))
1787     {
1788         skip("Failed to create device.\n");
1789         return;
1790     }
1791 
1792     memset(&heap_properties, 0, sizeof(heap_properties));
1793     heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
1794 
1795     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
1796     resource_desc.Alignment = 0;
1797     resource_desc.Width = 32;
1798     resource_desc.Height = 32;
1799     resource_desc.DepthOrArraySize = 1;
1800     resource_desc.MipLevels = 1;
1801     resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
1802     resource_desc.SampleDesc.Count = 1;
1803     resource_desc.SampleDesc.Quality = 0;
1804     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
1805     resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
1806 
1807     clear_value.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
1808     clear_value.Color[0] = 1.0f;
1809     clear_value.Color[1] = 0.0f;
1810     clear_value.Color[2] = 0.0f;
1811     clear_value.Color[3] = 1.0f;
1812 
1813     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1814             &resource_desc, D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
1815             &IID_ID3D12Resource, (void **)&resource);
1816     ok(hr == S_OK, "Failed to create committed resource, hr %#x.\n", hr);
1817 
1818     refcount = get_refcount(device);
1819     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1820     hr = ID3D12Resource_GetDevice(resource, &IID_ID3D12Device, (void **)&tmp_device);
1821     ok(hr == S_OK, "Failed to get device, hr %#x.\n", hr);
1822     refcount = get_refcount(device);
1823     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1824     refcount = ID3D12Device_Release(tmp_device);
1825     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
1826 
1827     check_interface(resource, &IID_ID3D12Object, true);
1828     check_interface(resource, &IID_ID3D12DeviceChild, true);
1829     check_interface(resource, &IID_ID3D12Pageable, true);
1830     check_interface(resource, &IID_ID3D12Resource, true);
1831 
1832     gpu_address = ID3D12Resource_GetGPUVirtualAddress(resource);
1833     ok(!gpu_address, "Got unexpected GPU virtual address %#"PRIx64".\n", gpu_address);
1834 
1835     refcount = ID3D12Resource_Release(resource);
1836     ok(!refcount, "ID3D12Resource has %u references left.\n", (unsigned int)refcount);
1837 
1838     resource_desc.MipLevels = 0;
1839     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1840             &resource_desc, D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
1841             &IID_ID3D12Resource, (void **)&resource);
1842     ok(hr == S_OK, "Failed to create committed resource, hr %#x.\n", hr);
1843     resource_desc = ID3D12Resource_GetDesc(resource);
1844     ok(resource_desc.MipLevels == 6, "Got unexpected miplevels %u.\n", resource_desc.MipLevels);
1845     ID3D12Resource_Release(resource);
1846     resource_desc.MipLevels = 10;
1847     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1848             &resource_desc, D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
1849             &IID_ID3D12Resource, (void **)&resource);
1850     ok(hr == S_OK, "Failed to create committed resource, hr %#x.\n", hr);
1851     resource_desc = ID3D12Resource_GetDesc(resource);
1852     ok(resource_desc.MipLevels == 10, "Got unexpected miplevels %u.\n", resource_desc.MipLevels);
1853     ID3D12Resource_Release(resource);
1854     resource_desc.MipLevels = 1;
1855 
1856     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1857             &resource_desc, D3D12_RESOURCE_STATE_RENDER_TARGET | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
1858             &clear_value, &IID_ID3D12Resource, (void **)&resource);
1859     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1860 
1861     /* For D3D12_RESOURCE_STATE_RENDER_TARGET the D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET flag is required. */
1862     resource_desc.Flags = 0;
1863     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1864             &resource_desc, D3D12_RESOURCE_STATE_RENDER_TARGET, NULL,
1865             &IID_ID3D12Resource, (void **)&resource);
1866     todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1867     if (SUCCEEDED(hr))
1868         ID3D12Resource_Release(resource);
1869 
1870     /* A texture cannot be created on a UPLOAD heap. */
1871     heap_properties.Type = D3D12_HEAP_TYPE_UPLOAD;
1872     resource = (void *)0xdeadbeef;
1873     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1874             &resource_desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL,
1875             &IID_ID3D12Resource, (void **)&resource);
1876     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1877     ok(!resource, "Got unexpected pointer %p.\n", resource);
1878 
1879     resource = (void *)0xdeadbeef;
1880     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1881             &resource_desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL,
1882             &IID_ID3D12Device, (void **)&resource);
1883     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1884     ok(!resource, "Got unexpected pointer %p.\n", resource);
1885 
1886     /* A texture cannot be created on a READBACK heap. */
1887     heap_properties.Type = D3D12_HEAP_TYPE_READBACK;
1888     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1889             &resource_desc, D3D12_RESOURCE_STATE_COPY_DEST, NULL,
1890             &IID_ID3D12Resource, (void **)&resource);
1891     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1892 
1893     heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
1894     resource_desc.Format = DXGI_FORMAT_BC1_UNORM;
1895     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1896             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
1897             &IID_ID3D12Resource, (void **)&resource);
1898     ok(hr == S_OK, "Failed to create committed resource, hr %#x.\n", hr);
1899     ID3D12Resource_Release(resource);
1900 
1901     resource_desc.Height = 31;
1902     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1903             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
1904             &IID_ID3D12Resource, (void **)&resource);
1905     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1906 
1907     resource_desc.Width = 31;
1908     resource_desc.Height = 32;
1909     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1910             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
1911             &IID_ID3D12Resource, (void **)&resource);
1912     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1913 
1914     resource_desc.Width = 30;
1915     resource_desc.Height = 30;
1916     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1917             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
1918             &IID_ID3D12Resource, (void **)&resource);
1919     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1920 
1921     resource_desc.Width = 2;
1922     resource_desc.Height = 2;
1923     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1924             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
1925             &IID_ID3D12Resource, (void **)&resource);
1926     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1927 
1928     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE1D;
1929     resource_desc.Width = 32;
1930     resource_desc.Height = 1;
1931     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1932             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
1933             &IID_ID3D12Resource, (void **)&resource);
1934     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1935 
1936     heap_properties.Type = D3D12_HEAP_TYPE_UPLOAD;
1937 
1938     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
1939     resource_desc.Alignment = 0;
1940     resource_desc.Width = 32;
1941     resource_desc.Height = 1;
1942     resource_desc.DepthOrArraySize = 1;
1943     resource_desc.MipLevels = 1;
1944     resource_desc.Format = DXGI_FORMAT_UNKNOWN;
1945     resource_desc.SampleDesc.Count = 1;
1946     resource_desc.SampleDesc.Quality = 0;
1947     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
1948     resource_desc.Flags = D3D12_RESOURCE_FLAG_NONE;
1949 
1950     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1951             &resource_desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL,
1952             &IID_ID3D12Resource, (void **)&resource);
1953     ok(hr == S_OK, "Failed to create committed resource, hr %#x.\n", hr);
1954 
1955     check_interface(resource, &IID_ID3D12Object, true);
1956     check_interface(resource, &IID_ID3D12DeviceChild, true);
1957     check_interface(resource, &IID_ID3D12Pageable, true);
1958     check_interface(resource, &IID_ID3D12Resource, true);
1959 
1960     gpu_address = ID3D12Resource_GetGPUVirtualAddress(resource);
1961     ok(gpu_address, "Got unexpected GPU virtual address %#"PRIx64".\n", gpu_address);
1962 
1963     refcount = ID3D12Resource_Release(resource);
1964     ok(!refcount, "ID3D12Resource has %u references left.\n", (unsigned int)refcount);
1965 
1966     resource_desc.MipLevels = 0;
1967     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1968             &resource_desc, D3D12_RESOURCE_STATE_GENERIC_READ, &clear_value,
1969             &IID_ID3D12Resource, (void **)&resource);
1970     ok(hr == E_INVALIDARG, "Failed to create committed resource, hr %#x.\n", hr);
1971     resource_desc.MipLevels = 1;
1972 
1973     /* The clear value must be NULL for buffers. */
1974     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1975             &resource_desc, D3D12_RESOURCE_STATE_GENERIC_READ, &clear_value,
1976             &IID_ID3D12Resource, (void **)&resource);
1977     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1978 
1979     /* For D3D12_HEAP_TYPE_UPLOAD the state must be D3D12_RESOURCE_STATE_GENERIC_READ. */
1980     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1981             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
1982             &IID_ID3D12Resource, (void **)&resource);
1983     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1984     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1985             &resource_desc, D3D12_RESOURCE_STATE_COPY_SOURCE, NULL,
1986             &IID_ID3D12Resource, (void **)&resource);
1987     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
1988 
1989     heap_properties.Type = D3D12_HEAP_TYPE_READBACK;
1990 
1991     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
1992             &resource_desc, D3D12_RESOURCE_STATE_COPY_DEST, NULL,
1993             &IID_ID3D12Resource, (void **)&resource);
1994     ok(hr == S_OK, "Failed to create committed resource, hr %#x.\n", hr);
1995 
1996     gpu_address = ID3D12Resource_GetGPUVirtualAddress(resource);
1997     ok(gpu_address, "Got unexpected GPU virtual address %#"PRIx64".\n", gpu_address);
1998 
1999     refcount = ID3D12Resource_Release(resource);
2000     ok(!refcount, "ID3D12Resource has %u references left.\n", (unsigned int)refcount);
2001 
2002     /* For D3D12_HEAP_TYPE_READBACK the state must be D3D12_RESOURCE_STATE_COPY_DEST. */
2003     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
2004             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
2005             &IID_ID3D12Resource, (void **)&resource);
2006     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2007     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
2008             &resource_desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL,
2009             &IID_ID3D12Resource, (void **)&resource);
2010     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2011     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
2012             &resource_desc, D3D12_RESOURCE_STATE_COPY_SOURCE, NULL,
2013             &IID_ID3D12Resource, (void **)&resource);
2014     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2015 
2016     for (i = 0; i < ARRAY_SIZE(invalid_buffer_desc_tests); ++i)
2017     {
2018         memset(&heap_properties, 0, sizeof(heap_properties));
2019         heap_properties.Type = invalid_buffer_desc_tests[i].heap_type;
2020 
2021         resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
2022         resource_desc.Alignment = 0;
2023         resource_desc.Width = 32;
2024         resource_desc.Height = 1;
2025         resource_desc.DepthOrArraySize = 1;
2026         resource_desc.MipLevels = 1;
2027         resource_desc.Format = DXGI_FORMAT_UNKNOWN;
2028         resource_desc.SampleDesc.Count = 1;
2029         resource_desc.SampleDesc.Quality = 0;
2030         resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
2031         resource_desc.Flags = invalid_buffer_desc_tests[i].flags;
2032 
2033         if (invalid_buffer_desc_tests[i].heap_type == D3D12_HEAP_TYPE_UPLOAD)
2034             state = D3D12_RESOURCE_STATE_GENERIC_READ;
2035         else
2036             state = D3D12_RESOURCE_STATE_COPY_DEST;
2037 
2038         hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
2039                 &resource_desc, state, NULL, &IID_ID3D12Resource, (void **)&resource);
2040         ok(hr == E_INVALIDARG, "Test %u: Got unexpected hr %#x.\n", i, hr);
2041     }
2042 
2043     refcount = ID3D12Device_Release(device);
2044     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
2045 }
2046 
test_create_heap(void)2047 static void test_create_heap(void)
2048 {
2049     D3D12_FEATURE_DATA_ARCHITECTURE architecture;
2050     D3D12_FEATURE_DATA_D3D12_OPTIONS options;
2051     D3D12_HEAP_DESC desc, result_desc;
2052     ID3D12Device *device, *tmp_device;
2053     bool is_pool_L1_supported;
2054     HRESULT hr, expected_hr;
2055     unsigned int i, j;
2056     ID3D12Heap *heap;
2057     ULONG refcount;
2058 
2059     static const struct
2060     {
2061         uint64_t alignment;
2062         HRESULT expected_hr;
2063     }
2064     tests[] =
2065     {
2066         {D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT,     S_OK},
2067         {D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,          S_OK},
2068         {2 * D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT, E_INVALIDARG},
2069         {2 * D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,      E_INVALIDARG},
2070         {D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT,            E_INVALIDARG},
2071     };
2072     static const struct
2073     {
2074         D3D12_HEAP_FLAGS flags;
2075         const char *name;
2076     }
2077     heap_flags[] =
2078     {
2079         {D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS, "buffers"},
2080         {D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, "textures"},
2081         {D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES, "rt_ds_textures"},
2082     };
2083     static const struct
2084     {
2085         D3D12_CPU_PAGE_PROPERTY page_property;
2086         D3D12_MEMORY_POOL pool_preference;
2087         HRESULT expected_hr;
2088     }
2089     custom_tests[] =
2090     {
2091         {D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_MEMORY_POOL_UNKNOWN, E_INVALIDARG},
2092         {D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE, D3D12_MEMORY_POOL_UNKNOWN, E_INVALIDARG},
2093         {D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE, D3D12_MEMORY_POOL_UNKNOWN, E_INVALIDARG},
2094         {D3D12_CPU_PAGE_PROPERTY_WRITE_BACK, D3D12_MEMORY_POOL_UNKNOWN, E_INVALIDARG},
2095         {D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_MEMORY_POOL_L0, E_INVALIDARG},
2096         {D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE, D3D12_MEMORY_POOL_L0, S_OK},
2097         {D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE, D3D12_MEMORY_POOL_L0, S_OK},
2098         {D3D12_CPU_PAGE_PROPERTY_WRITE_BACK, D3D12_MEMORY_POOL_L0, S_OK},
2099         {D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_MEMORY_POOL_L1, E_INVALIDARG},
2100         {D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE, D3D12_MEMORY_POOL_L1, S_OK},
2101         {D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE, D3D12_MEMORY_POOL_L1, E_INVALIDARG},
2102         {D3D12_CPU_PAGE_PROPERTY_WRITE_BACK, D3D12_MEMORY_POOL_L1, E_INVALIDARG},
2103     };
2104 
2105     if (!(device = create_device()))
2106     {
2107         skip("Failed to create device.\n");
2108         return;
2109     }
2110 
2111     desc.SizeInBytes = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
2112     memset(&desc.Properties, 0, sizeof(desc.Properties));
2113     desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT;
2114     desc.Alignment = 0;
2115     desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES;
2116     hr = ID3D12Device_CreateHeap(device, &desc, &IID_ID3D12Heap, (void **)&heap);
2117     ok(hr == S_OK, "Failed to create heap, hr %#x.\n", hr);
2118 
2119     refcount = get_refcount(device);
2120     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2121     hr = ID3D12Heap_GetDevice(heap, &IID_ID3D12Device, (void **)&tmp_device);
2122     ok(hr == S_OK, "Failed to get device, hr %#x.\n", hr);
2123     refcount = get_refcount(device);
2124     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2125     refcount = ID3D12Device_Release(tmp_device);
2126     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2127 
2128     check_interface(heap, &IID_ID3D12Object, true);
2129     check_interface(heap, &IID_ID3D12DeviceChild, true);
2130     check_interface(heap, &IID_ID3D12Pageable, true);
2131     check_interface(heap, &IID_ID3D12Heap, true);
2132 
2133     result_desc = ID3D12Heap_GetDesc(heap);
2134     check_heap_desc(&result_desc, &desc);
2135 
2136     refcount = ID3D12Heap_Release(heap);
2137     ok(!refcount, "ID3D12Heap has %u references left.\n", (unsigned int)refcount);
2138 
2139     desc.SizeInBytes = 0;
2140     hr = ID3D12Device_CreateHeap(device, &desc, &IID_ID3D12Heap, (void **)&heap);
2141     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2142 
2143     desc.SizeInBytes = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
2144     desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES | D3D12_HEAP_FLAG_ALLOW_DISPLAY;
2145     hr = ID3D12Device_CreateHeap(device, &desc, &IID_ID3D12Heap, (void **)&heap);
2146     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2147 
2148     heap = (void *)0xdeadbeef;
2149     desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES | D3D12_HEAP_FLAG_ALLOW_DISPLAY;
2150     hr = ID3D12Device_CreateHeap(device, &desc, &IID_ID3D12Heap, (void **)&heap);
2151     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2152     ok(!heap, "Got unexpected pointer %p.\n", heap);
2153 
2154     for (i = 0; i < ARRAY_SIZE(tests); ++i)
2155     {
2156         for (j = 0; j < ARRAY_SIZE(heap_flags); ++j)
2157         {
2158             vkd3d_test_set_context("Test %u, %u", i, j);
2159 
2160             desc.SizeInBytes = 10 * tests[i].alignment;
2161             desc.Alignment = tests[i].alignment;
2162             desc.Flags = heap_flags[j].flags;
2163             hr = ID3D12Device_CreateHeap(device, &desc, &IID_ID3D12Heap, (void **)&heap);
2164             ok(hr == tests[i].expected_hr, "Test %u, %s: Got hr %#x, expected %#x.\n",
2165                     i, heap_flags[j].name, hr, tests[i].expected_hr);
2166             if (FAILED(hr))
2167                 continue;
2168 
2169             result_desc = ID3D12Heap_GetDesc(heap);
2170             check_heap_desc(&result_desc, &desc);
2171 
2172             refcount = ID3D12Heap_Release(heap);
2173             ok(!refcount, "ID3D12Heap has %u references left.\n", (unsigned int)refcount);
2174         }
2175     }
2176     vkd3d_test_set_context(NULL);
2177 
2178     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options));
2179     ok(hr == S_OK, "Failed to check feature support, hr %#x.\n", hr);
2180     if (options.ResourceHeapTier < D3D12_RESOURCE_HEAP_TIER_2)
2181     {
2182         skip("Resource heap tier %u.\n", options.ResourceHeapTier);
2183         goto done;
2184     }
2185 
2186     desc.SizeInBytes = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
2187     desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
2188     desc.Flags = D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES;
2189     hr = ID3D12Device_CreateHeap(device, &desc, &IID_ID3D12Heap, (void **)&heap);
2190     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
2191     result_desc = ID3D12Heap_GetDesc(heap);
2192     check_heap_desc(&result_desc, &desc);
2193     refcount = ID3D12Heap_Release(heap);
2194     ok(!refcount, "ID3D12Heap has %u references left.\n", (unsigned int)refcount);
2195 
2196     memset(&architecture, 0, sizeof(architecture));
2197     hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_ARCHITECTURE, &architecture, sizeof(architecture));
2198     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
2199     for (i = D3D12_HEAP_TYPE_DEFAULT; i < D3D12_HEAP_TYPE_CUSTOM; ++i)
2200     {
2201         vkd3d_test_set_context("Test %u\n", i);
2202         desc.Properties = ID3D12Device_GetCustomHeapProperties(device, 1, i);
2203         ok(desc.Properties.Type == D3D12_HEAP_TYPE_CUSTOM, "Got unexpected heap type %#x.\n", desc.Properties.Type);
2204 
2205         switch (i)
2206         {
2207             case D3D12_HEAP_TYPE_DEFAULT:
2208                 ok(desc.Properties.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE,
2209                         "Got unexpected CPUPageProperty %#x.\n", desc.Properties.CPUPageProperty);
2210                 ok(desc.Properties.MemoryPoolPreference == (architecture.UMA
2211                         ? D3D12_MEMORY_POOL_L0 : D3D12_MEMORY_POOL_L1),
2212                         "Got unexpected MemoryPoolPreference %#x.\n", desc.Properties.MemoryPoolPreference);
2213                 break;
2214 
2215             case D3D12_HEAP_TYPE_UPLOAD:
2216                 ok(desc.Properties.CPUPageProperty == (architecture.CacheCoherentUMA
2217                         ? D3D12_CPU_PAGE_PROPERTY_WRITE_BACK : D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE),
2218                         "Got unexpected CPUPageProperty %#x.\n", desc.Properties.CPUPageProperty);
2219                 ok(desc.Properties.MemoryPoolPreference == D3D12_MEMORY_POOL_L0,
2220                         "Got unexpected MemoryPoolPreference %#x.\n", desc.Properties.MemoryPoolPreference);
2221                 break;
2222 
2223             case D3D12_HEAP_TYPE_READBACK:
2224                 ok(desc.Properties.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK,
2225                         "Got unexpected CPUPageProperty %#x.\n", desc.Properties.CPUPageProperty);
2226                 ok(desc.Properties.MemoryPoolPreference == D3D12_MEMORY_POOL_L0,
2227                         "Got unexpected MemoryPoolPreference %#x.\n", desc.Properties.MemoryPoolPreference);
2228                 break;
2229 
2230             default:
2231               ok(0, "Invalid heap type %#x.\n", i);
2232               continue;
2233         }
2234 
2235         hr = ID3D12Device_CreateHeap(device, &desc, &IID_ID3D12Heap, (void **)&heap);
2236         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
2237         result_desc = ID3D12Heap_GetDesc(heap);
2238         check_heap_desc(&result_desc, &desc);
2239         ID3D12Heap_Release(heap);
2240     }
2241     vkd3d_test_set_context(NULL);
2242 
2243     is_pool_L1_supported = is_memory_pool_L1_supported(device);
2244     desc.Properties.Type = D3D12_HEAP_TYPE_CUSTOM;
2245     desc.Properties.CreationNodeMask = 1;
2246     desc.Properties.VisibleNodeMask = 1;
2247     for (i = 0; i < ARRAY_SIZE(custom_tests); ++i)
2248     {
2249         vkd3d_test_set_context("Test %u", i);
2250 
2251         desc.Properties.CPUPageProperty = custom_tests[i].page_property;
2252         desc.Properties.MemoryPoolPreference = custom_tests[i].pool_preference;
2253         hr = ID3D12Device_CreateHeap(device, &desc, &IID_ID3D12Heap, (void **)&heap);
2254         expected_hr = (custom_tests[i].pool_preference != D3D12_MEMORY_POOL_L1 || is_pool_L1_supported) ? custom_tests[i].expected_hr : E_INVALIDARG;
2255         ok(hr == expected_hr, "Test %u, page_property %u, pool_preference %u: Got hr %#x, expected %#x.\n",
2256                 i, custom_tests[i].page_property, custom_tests[i].pool_preference, hr, expected_hr);
2257         if (FAILED(hr))
2258             continue;
2259 
2260         result_desc = ID3D12Heap_GetDesc(heap);
2261         check_heap_desc(&result_desc, &desc);
2262 
2263         refcount = ID3D12Heap_Release(heap);
2264         ok(!refcount, "ID3D12Heap has %u references left.\n", (unsigned int)refcount);
2265     }
2266     vkd3d_test_set_context(NULL);
2267 
2268 done:
2269     refcount = ID3D12Device_Release(device);
2270     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
2271 }
2272 
test_create_placed_resource(void)2273 static void test_create_placed_resource(void)
2274 {
2275     D3D12_GPU_VIRTUAL_ADDRESS gpu_address;
2276     D3D12_RESOURCE_DESC resource_desc;
2277     ID3D12Device *device, *tmp_device;
2278     D3D12_CLEAR_VALUE clear_value;
2279     D3D12_RESOURCE_STATES state;
2280     D3D12_HEAP_DESC heap_desc;
2281     ID3D12Resource *resource;
2282     ID3D12Heap *heap;
2283     unsigned int i;
2284     ULONG refcount;
2285     HRESULT hr;
2286 
2287     static const struct
2288     {
2289         D3D12_HEAP_TYPE heap_type;
2290         D3D12_RESOURCE_FLAGS flags;
2291     }
2292     invalid_buffer_desc_tests[] =
2293     {
2294         /* Render target or unordered access resources are not allowed with UPLOAD or READBACK. */
2295         {D3D12_HEAP_TYPE_UPLOAD,   D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET},
2296         {D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET},
2297         {D3D12_HEAP_TYPE_UPLOAD,   D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS},
2298         {D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS},
2299     };
2300 
2301     if (!(device = create_device()))
2302     {
2303         skip("Failed to create device.\n");
2304         return;
2305     }
2306 
2307     heap_desc.SizeInBytes = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
2308     memset(&heap_desc.Properties, 0, sizeof(heap_desc.Properties));
2309     heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT;
2310     heap_desc.Alignment = 0;
2311     heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
2312     hr = ID3D12Device_CreateHeap(device, &heap_desc, &IID_ID3D12Heap, (void **)&heap);
2313     ok(hr == S_OK, "Failed to create heap, hr %#x.\n", hr);
2314 
2315     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
2316     resource_desc.Alignment = 0;
2317     resource_desc.Width = 32;
2318     resource_desc.Height = 1;
2319     resource_desc.DepthOrArraySize = 1;
2320     resource_desc.MipLevels = 1;
2321     resource_desc.Format = DXGI_FORMAT_UNKNOWN;
2322     resource_desc.SampleDesc.Count = 1;
2323     resource_desc.SampleDesc.Quality = 0;
2324     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
2325     resource_desc.Flags = 0;
2326 
2327     clear_value.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
2328     clear_value.Color[0] = 1.0f;
2329     clear_value.Color[1] = 0.0f;
2330     clear_value.Color[2] = 0.0f;
2331     clear_value.Color[3] = 1.0f;
2332 
2333     refcount = get_refcount(heap);
2334     ok(refcount == 1, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2335 
2336     hr = ID3D12Device_CreatePlacedResource(device, heap, 0,
2337             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
2338             &IID_ID3D12Resource, (void **)&resource);
2339     ok(hr == S_OK, "Failed to create placed resource, hr %#x.\n", hr);
2340 
2341     refcount = get_refcount(heap);
2342     ok(refcount == 1, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2343 
2344     refcount = get_refcount(device);
2345     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2346     hr = ID3D12Resource_GetDevice(resource, &IID_ID3D12Device, (void **)&tmp_device);
2347     ok(hr == S_OK, "Failed to get device, hr %#x.\n", hr);
2348     refcount = get_refcount(device);
2349     ok(refcount == 4, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2350     refcount = ID3D12Device_Release(tmp_device);
2351     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2352 
2353     check_interface(resource, &IID_ID3D12Object, true);
2354     check_interface(resource, &IID_ID3D12DeviceChild, true);
2355     check_interface(resource, &IID_ID3D12Pageable, true);
2356     check_interface(resource, &IID_ID3D12Resource, true);
2357 
2358     gpu_address = ID3D12Resource_GetGPUVirtualAddress(resource);
2359     ok(gpu_address, "Got unexpected GPU virtual address %#"PRIx64".\n", gpu_address);
2360 
2361     refcount = ID3D12Resource_Release(resource);
2362     ok(!refcount, "ID3D12Resource has %u references left.\n", (unsigned int)refcount);
2363 
2364     /* The clear value must be NULL for buffers. */
2365     hr = ID3D12Device_CreatePlacedResource(device, heap, 0,
2366             &resource_desc, D3D12_RESOURCE_STATE_COMMON, &clear_value,
2367             &IID_ID3D12Resource, (void **)&resource);
2368     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2369 
2370     ID3D12Heap_Release(heap);
2371 
2372     for (i = 0; i < ARRAY_SIZE(invalid_buffer_desc_tests); ++i)
2373     {
2374         heap_desc.SizeInBytes = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
2375         memset(&heap_desc.Properties, 0, sizeof(heap_desc.Properties));
2376         heap_desc.Properties.Type = invalid_buffer_desc_tests[i].heap_type;
2377         heap_desc.Alignment = 0;
2378         heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
2379         hr = ID3D12Device_CreateHeap(device, &heap_desc, &IID_ID3D12Heap, (void **)&heap);
2380         ok(hr == S_OK, "Test %u: Failed to create heap, hr %#x.\n", i, hr);
2381 
2382         resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
2383         resource_desc.Alignment = 0;
2384         resource_desc.Width = 32;
2385         resource_desc.Height = 1;
2386         resource_desc.DepthOrArraySize = 1;
2387         resource_desc.MipLevels = 1;
2388         resource_desc.Format = DXGI_FORMAT_UNKNOWN;
2389         resource_desc.SampleDesc.Count = 1;
2390         resource_desc.SampleDesc.Quality = 0;
2391         resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
2392         resource_desc.Flags = invalid_buffer_desc_tests[i].flags;
2393 
2394         if (invalid_buffer_desc_tests[i].heap_type == D3D12_HEAP_TYPE_UPLOAD)
2395             state = D3D12_RESOURCE_STATE_GENERIC_READ;
2396         else
2397             state = D3D12_RESOURCE_STATE_COPY_DEST;
2398 
2399         hr = ID3D12Device_CreatePlacedResource(device, heap, 0,
2400                 &resource_desc, state, &clear_value, &IID_ID3D12Resource, (void **)&resource);
2401         ok(hr == E_INVALIDARG, "Test %u: Got unexpected hr %#x.\n", i, hr);
2402 
2403         ID3D12Heap_Release(heap);
2404     }
2405 
2406     refcount = ID3D12Device_Release(device);
2407     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
2408 }
2409 
test_create_reserved_resource(void)2410 static void test_create_reserved_resource(void)
2411 {
2412     D3D12_GPU_VIRTUAL_ADDRESS gpu_address;
2413     D3D12_HEAP_PROPERTIES heap_properties;
2414     D3D12_RESOURCE_DESC resource_desc;
2415     D3D12_CLEAR_VALUE clear_value;
2416     D3D12_HEAP_FLAGS heap_flags;
2417     ID3D12Resource *resource;
2418     bool standard_swizzle;
2419     ID3D12Device *device;
2420     ULONG refcount;
2421     HRESULT hr;
2422     void *ptr;
2423 
2424     if (!(device = create_device()))
2425     {
2426         skip("Failed to create device.\n");
2427         return;
2428     }
2429 
2430     if (get_tiled_resources_tier(device) == D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED)
2431     {
2432         skip("Tiled resources are not supported.\n");
2433         goto done;
2434     }
2435 
2436     standard_swizzle = is_standard_swizzle_64kb_supported(device);
2437     trace("Standard swizzle 64KB: %#x.\n", standard_swizzle);
2438 
2439     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
2440     resource_desc.Alignment = 0;
2441     resource_desc.Width = 32;
2442     resource_desc.Height = 1;
2443     resource_desc.DepthOrArraySize = 1;
2444     resource_desc.MipLevels = 1;
2445     resource_desc.Format = DXGI_FORMAT_UNKNOWN;
2446     resource_desc.SampleDesc.Count = 1;
2447     resource_desc.SampleDesc.Quality = 0;
2448     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
2449     resource_desc.Flags = 0;
2450 
2451     hr = ID3D12Device_CreateReservedResource(device,
2452             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
2453             &IID_ID3D12Resource, (void **)&resource);
2454     ok(hr == S_OK, "Failed to create reserved resource, hr %#x.\n", hr);
2455 
2456     check_interface(resource, &IID_ID3D12Object, true);
2457     check_interface(resource, &IID_ID3D12DeviceChild, true);
2458     check_interface(resource, &IID_ID3D12Pageable, true);
2459     check_interface(resource, &IID_ID3D12Resource, true);
2460 
2461     gpu_address = ID3D12Resource_GetGPUVirtualAddress(resource);
2462     ok(gpu_address, "Got unexpected GPU virtual address %#"PRIx64".\n", gpu_address);
2463 
2464     heap_flags = 0xdeadbeef;
2465     hr = ID3D12Resource_GetHeapProperties(resource, &heap_properties, &heap_flags);
2466     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2467     ok(heap_flags == 0xdeadbeef, "Got unexpected heap flags %#x.\n", heap_flags);
2468 
2469     /* Map() is not allowed on reserved resources */
2470     hr = ID3D12Resource_Map(resource, 0, NULL, &ptr);
2471     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2472 
2473     refcount = ID3D12Resource_Release(resource);
2474     ok(!refcount, "ID3D12Resource has %u references left.\n", (unsigned int)refcount);
2475 
2476     /* The clear value must be NULL for buffers. */
2477     clear_value.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
2478     clear_value.Color[0] = 1.0f;
2479     clear_value.Color[1] = 0.0f;
2480     clear_value.Color[2] = 0.0f;
2481     clear_value.Color[3] = 1.0f;
2482 
2483     hr = ID3D12Device_CreateReservedResource(device,
2484             &resource_desc, D3D12_RESOURCE_STATE_COMMON, &clear_value,
2485             &IID_ID3D12Resource, (void **)&resource);
2486     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2487 
2488     /* D3D12_TEXTURE_LAYOUT_ROW_MAJOR must be used for buffers. */
2489     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE;
2490     hr = ID3D12Device_CreateReservedResource(device,
2491             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
2492             &IID_ID3D12Resource, (void **)&resource);
2493     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2494 
2495     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
2496     hr = ID3D12Device_CreateReservedResource(device,
2497             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
2498             &IID_ID3D12Resource, (void **)&resource);
2499     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2500 
2501     /* D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE must be used for textures. */
2502     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
2503     resource_desc.Alignment = 0;
2504     resource_desc.Width = 64;
2505     resource_desc.Height = 64;
2506     resource_desc.DepthOrArraySize = 1;
2507     resource_desc.MipLevels = 4;
2508     resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
2509     resource_desc.SampleDesc.Count = 1;
2510     resource_desc.SampleDesc.Quality = 0;
2511     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE;
2512     resource_desc.Flags = 0;
2513 
2514     hr = ID3D12Device_CreateReservedResource(device,
2515             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
2516             &IID_ID3D12Resource, (void **)&resource);
2517     ok(hr == S_OK, "Failed to create reserved resource, hr %#x.\n", hr);
2518     refcount = ID3D12Resource_Release(resource);
2519     ok(!refcount, "ID3D12Resource has %u references left.\n", (unsigned int)refcount);
2520 
2521     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
2522     hr = ID3D12Device_CreateReservedResource(device,
2523             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
2524             &IID_ID3D12Resource, (void **)&resource);
2525     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2526 
2527     resource_desc.MipLevels = 1;
2528     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
2529     hr = ID3D12Device_CreateReservedResource(device,
2530             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
2531             &IID_ID3D12Resource, (void **)&resource);
2532     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2533 
2534     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE;
2535     hr = ID3D12Device_CreateReservedResource(device,
2536             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
2537             &IID_ID3D12Resource, (void **)&resource);
2538     ok(hr == (standard_swizzle ? S_OK : E_INVALIDARG) || broken(use_warp_device), "Got unexpected hr %#x.\n", hr);
2539     if (SUCCEEDED(hr))
2540         ID3D12Resource_Release(resource);
2541 
2542 done:
2543     refcount = ID3D12Device_Release(device);
2544     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
2545 }
2546 
test_create_descriptor_heap(void)2547 static void test_create_descriptor_heap(void)
2548 {
2549     D3D12_DESCRIPTOR_HEAP_DESC heap_desc;
2550     ID3D12Device *device, *tmp_device;
2551     ID3D12DescriptorHeap *heap;
2552     ULONG refcount;
2553     HRESULT hr;
2554 
2555     if (!(device = create_device()))
2556     {
2557         skip("Failed to create device.\n");
2558         return;
2559     }
2560 
2561     heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
2562     heap_desc.NumDescriptors = 16;
2563     heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
2564     heap_desc.NodeMask = 0;
2565     hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc, &IID_ID3D12DescriptorHeap, (void **)&heap);
2566     ok(hr == S_OK, "Failed to create descriptor heap, hr %#x.\n", hr);
2567 
2568     refcount = get_refcount(device);
2569     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2570     hr = ID3D12DescriptorHeap_GetDevice(heap, &IID_ID3D12Device, (void **)&tmp_device);
2571     ok(hr == S_OK, "Failed to get device, hr %#x.\n", hr);
2572     refcount = get_refcount(device);
2573     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2574     refcount = ID3D12Device_Release(tmp_device);
2575     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2576 
2577     check_interface(heap, &IID_ID3D12Object, true);
2578     check_interface(heap, &IID_ID3D12DeviceChild, true);
2579     check_interface(heap, &IID_ID3D12Pageable, true);
2580     check_interface(heap, &IID_ID3D12DescriptorHeap, true);
2581 
2582     refcount = ID3D12DescriptorHeap_Release(heap);
2583     ok(!refcount, "ID3D12DescriptorHeap has %u references left.\n", (unsigned int)refcount);
2584 
2585     heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
2586     heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
2587     hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc, &IID_ID3D12DescriptorHeap, (void **)&heap);
2588     ok(hr == S_OK, "Failed to create descriptor heap, hr %#x.\n", hr);
2589     refcount = ID3D12DescriptorHeap_Release(heap);
2590     ok(!refcount, "ID3D12DescriptorHeap has %u references left.\n", (unsigned int)refcount);
2591 
2592     heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
2593     heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
2594     hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc, &IID_ID3D12DescriptorHeap, (void **)&heap);
2595     ok(hr == S_OK, "Failed to create descriptor heap, hr %#x.\n", hr);
2596     refcount = ID3D12DescriptorHeap_Release(heap);
2597     ok(!refcount, "ID3D12DescriptorHeap has %u references left.\n", (unsigned int)refcount);
2598 
2599     heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
2600     heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
2601     hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc, &IID_ID3D12DescriptorHeap, (void **)&heap);
2602     ok(hr == S_OK, "Failed to create descriptor heap, hr %#x.\n", hr);
2603     refcount = ID3D12DescriptorHeap_Release(heap);
2604     ok(!refcount, "ID3D12DescriptorHeap has %u references left.\n", (unsigned int)refcount);
2605 
2606     heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
2607     hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc, &IID_ID3D12DescriptorHeap, (void **)&heap);
2608     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2609 
2610     heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
2611     heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
2612     hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc, &IID_ID3D12DescriptorHeap, (void **)&heap);
2613     ok(hr == S_OK, "Failed to create descriptor heap, hr %#x.\n", hr);
2614     refcount = ID3D12DescriptorHeap_Release(heap);
2615     ok(!refcount, "ID3D12DescriptorHeap has %u references left.\n", (unsigned int)refcount);
2616 
2617     heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
2618     hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc, &IID_ID3D12DescriptorHeap, (void **)&heap);
2619     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2620 
2621     refcount = ID3D12Device_Release(device);
2622     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
2623 }
2624 
test_create_sampler(void)2625 static void test_create_sampler(void)
2626 {
2627     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
2628     D3D12_DESCRIPTOR_HEAP_DESC heap_desc;
2629     unsigned int sampler_increment_size;
2630     D3D12_SAMPLER_DESC sampler_desc;
2631     ID3D12DescriptorHeap *heap;
2632     ID3D12Device *device;
2633     unsigned int i;
2634     ULONG refcount;
2635     HRESULT hr;
2636 
2637     if (!(device = create_device()))
2638     {
2639         skip("Failed to create device.\n");
2640         return;
2641     }
2642 
2643     sampler_increment_size = ID3D12Device_GetDescriptorHandleIncrementSize(device,
2644             D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
2645     trace("Sampler descriptor handle increment size: %u.\n", sampler_increment_size);
2646     ok(sampler_increment_size, "Got unexpected increment size %#x.\n", sampler_increment_size);
2647 
2648     heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
2649     heap_desc.NumDescriptors = 16;
2650     heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
2651     heap_desc.NodeMask = 0;
2652     hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc, &IID_ID3D12DescriptorHeap, (void **)&heap);
2653     ok(SUCCEEDED(hr), "Failed to create descriptor heap, hr %#x.\n", hr);
2654 
2655     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
2656     memset(&sampler_desc, 0, sizeof(sampler_desc));
2657     sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
2658     sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
2659     sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
2660     sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
2661     sampler_desc.MaxLOD = D3D12_FLOAT32_MAX;
2662     ID3D12Device_CreateSampler(device, &sampler_desc, cpu_handle);
2663 
2664     cpu_handle.ptr += sampler_increment_size;
2665     sampler_desc.Filter = D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR;
2666     for (i = 1; i < heap_desc.NumDescriptors; ++i)
2667     {
2668         ID3D12Device_CreateSampler(device, &sampler_desc, cpu_handle);
2669         cpu_handle.ptr += sampler_increment_size;
2670     }
2671 
2672     trace("MinMaxFiltering: %#x.\n", is_min_max_filtering_supported(device));
2673     if (is_min_max_filtering_supported(device))
2674     {
2675         cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
2676         sampler_desc.Filter = D3D12_FILTER_MINIMUM_MIN_MAG_MIP_POINT;
2677         ID3D12Device_CreateSampler(device, &sampler_desc, cpu_handle);
2678 
2679         cpu_handle.ptr += sampler_increment_size;
2680         sampler_desc.Filter = D3D12_FILTER_MAXIMUM_MIN_MAG_MIP_POINT;
2681         ID3D12Device_CreateSampler(device, &sampler_desc, cpu_handle);
2682     }
2683 
2684     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
2685     sampler_desc.Filter = D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT;
2686     sampler_desc.ComparisonFunc = D3D12_COMPARISON_FUNC_LESS;
2687     ID3D12Device_CreateSampler(device, &sampler_desc, cpu_handle);
2688 
2689     refcount = ID3D12DescriptorHeap_Release(heap);
2690     ok(!refcount, "ID3D12DescriptorHeap has %u references left.\n", (unsigned int)refcount);
2691     refcount = ID3D12Device_Release(device);
2692     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
2693 }
2694 
test_create_unordered_access_view(void)2695 static void test_create_unordered_access_view(void)
2696 {
2697     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
2698     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
2699     ID3D12Resource *buffer, *texture;
2700     unsigned int descriptor_size;
2701     ID3D12DescriptorHeap *heap;
2702     ID3D12Device *device;
2703     ULONG refcount;
2704 
2705     if (!(device = create_device()))
2706     {
2707         skip("Failed to create device.\n");
2708         return;
2709     }
2710 
2711     descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(device,
2712             D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
2713     trace("CBV/SRV/UAV descriptor size: %u.\n", descriptor_size);
2714     ok(descriptor_size, "Got unexpected descriptor size %#x.\n", descriptor_size);
2715 
2716     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 16);
2717 
2718     buffer = create_default_buffer(device, 64 * sizeof(float),
2719             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
2720 
2721     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
2722     uav_desc.Format = DXGI_FORMAT_R32_FLOAT;
2723     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
2724     uav_desc.Buffer.FirstElement = 0;
2725     uav_desc.Buffer.NumElements = 64;
2726     uav_desc.Buffer.StructureByteStride = 0;
2727     uav_desc.Buffer.CounterOffsetInBytes = 0;
2728     uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
2729     ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc, cpu_handle);
2730 
2731     cpu_handle.ptr += descriptor_size;
2732 
2733     /* DXGI_FORMAT_R32_UINT view for DXGI_FORMAT_R8G8B8A8_TYPELESS resources. */
2734     texture = create_default_texture(device, 8, 8, DXGI_FORMAT_R8G8B8A8_TYPELESS,
2735             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
2736 
2737     uav_desc.Format = DXGI_FORMAT_R32_UINT;
2738     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
2739     uav_desc.Texture2D.MipSlice = 0;
2740     uav_desc.Texture2D.PlaneSlice = 0;
2741     ID3D12Device_CreateUnorderedAccessView(device, texture, NULL, &uav_desc, cpu_handle);
2742 
2743     ID3D12Resource_Release(buffer);
2744     ID3D12Resource_Release(texture);
2745     refcount = ID3D12DescriptorHeap_Release(heap);
2746     ok(!refcount, "ID3D12DescriptorHeap has %u references left.\n", (unsigned int)refcount);
2747     refcount = ID3D12Device_Release(device);
2748     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
2749 }
2750 
test_create_root_signature(void)2751 static void test_create_root_signature(void)
2752 {
2753     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
2754     D3D12_DESCRIPTOR_RANGE descriptor_ranges[2];
2755     D3D12_ROOT_PARAMETER root_parameters[3];
2756     ID3D12RootSignature *root_signature;
2757     ID3D12Device *device, *tmp_device;
2758     ULONG refcount;
2759     HRESULT hr;
2760 
2761     if (!(device = create_device()))
2762     {
2763         skip("Failed to create device.\n");
2764         return;
2765     }
2766 
2767     /* descriptor table */
2768     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
2769     descriptor_ranges[0].NumDescriptors = 1;
2770     descriptor_ranges[0].BaseShaderRegister = 0;
2771     descriptor_ranges[0].RegisterSpace = 0;
2772     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
2773     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2774     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
2775     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
2776     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
2777     root_signature_desc.NumParameters = 1;
2778     root_signature_desc.pParameters = root_parameters;
2779     root_signature_desc.NumStaticSamplers = 0;
2780     root_signature_desc.pStaticSamplers = NULL;
2781     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
2782     hr = create_root_signature(device, &root_signature_desc, &root_signature);
2783     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
2784 
2785     refcount = get_refcount(device);
2786     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2787     hr = ID3D12RootSignature_GetDevice(root_signature, &IID_ID3D12Device, (void **)&tmp_device);
2788     ok(hr == S_OK, "Failed to get device, hr %#x.\n", hr);
2789     refcount = get_refcount(device);
2790     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2791     refcount = ID3D12Device_Release(tmp_device);
2792     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2793 
2794     check_interface(root_signature, &IID_ID3D12Object, true);
2795     check_interface(root_signature, &IID_ID3D12DeviceChild, true);
2796     check_interface(root_signature, &IID_ID3D12Pageable, false);
2797     check_interface(root_signature, &IID_ID3D12RootSignature, true);
2798 
2799     refcount = ID3D12RootSignature_Release(root_signature);
2800     ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
2801 
2802     /* sampler and SRV in the same descriptor table */
2803     descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
2804     descriptor_ranges[1].NumDescriptors = 1;
2805     descriptor_ranges[1].BaseShaderRegister = 2;
2806     descriptor_ranges[1].RegisterSpace = 0;
2807     descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 10;
2808     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2809     root_parameters[0].DescriptorTable.NumDescriptorRanges = 2;
2810     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
2811     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
2812     root_signature_desc.NumParameters = 1;
2813     root_signature_desc.pParameters = root_parameters;
2814     root_signature_desc.NumStaticSamplers = 0;
2815     root_signature_desc.pStaticSamplers = NULL;
2816     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
2817     hr = create_root_signature(device, &root_signature_desc, &root_signature);
2818     ok(hr == E_INVALIDARG, "Failed to create root signature, hr %#x.\n", hr);
2819 
2820     /* empty root signature */
2821     root_signature_desc.NumParameters = 0;
2822     root_signature_desc.pParameters = NULL;
2823     root_signature_desc.NumStaticSamplers = 0;
2824     root_signature_desc.pStaticSamplers = NULL;
2825     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
2826     hr = create_root_signature(device, &root_signature_desc, &root_signature);
2827     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
2828     refcount = ID3D12RootSignature_Release(root_signature);
2829     ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
2830 
2831     /* root constants */
2832     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
2833     root_parameters[0].Constants.ShaderRegister = 0;
2834     root_parameters[0].Constants.RegisterSpace = 0;
2835     root_parameters[0].Constants.Num32BitValues = 4;
2836     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
2837     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
2838     root_parameters[1].Constants.ShaderRegister = 0;
2839     root_parameters[1].Constants.RegisterSpace = 0;
2840     root_parameters[1].Constants.Num32BitValues = 8;
2841     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
2842     root_signature_desc.NumParameters = 2;
2843     root_signature_desc.pParameters = root_parameters;
2844     root_signature_desc.NumStaticSamplers = 0;
2845     root_signature_desc.pStaticSamplers = NULL;
2846     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
2847     hr = create_root_signature(device, &root_signature_desc, &root_signature);
2848     todo ok(hr == E_FAIL || hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2849     if (SUCCEEDED(hr))
2850         ID3D12RootSignature_Release(root_signature);
2851     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
2852     hr = create_root_signature(device, &root_signature_desc, &root_signature);
2853     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
2854     refcount = ID3D12RootSignature_Release(root_signature);
2855     ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
2856 
2857     root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
2858     root_parameters[2].Constants.ShaderRegister = 1;
2859     root_parameters[2].Constants.RegisterSpace = 0;
2860     root_parameters[2].Constants.Num32BitValues = 3;
2861     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
2862     root_signature_desc.NumParameters = 3;
2863     hr = create_root_signature(device, &root_signature_desc, &root_signature);
2864     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
2865     refcount = ID3D12RootSignature_Release(root_signature);
2866     ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
2867 
2868     /* root descriptors */
2869     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
2870     root_parameters[0].Descriptor.ShaderRegister = 0;
2871     root_parameters[0].Descriptor.RegisterSpace = 0;
2872     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
2873     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
2874     root_parameters[1].Descriptor.ShaderRegister = 0;
2875     root_parameters[1].Descriptor.RegisterSpace = 0;
2876     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
2877     root_signature_desc.NumParameters = 2;
2878     root_signature_desc.pParameters = root_parameters;
2879     root_signature_desc.NumStaticSamplers = 0;
2880     root_signature_desc.pStaticSamplers = NULL;
2881     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
2882     hr = create_root_signature(device, &root_signature_desc, &root_signature);
2883     todo ok(hr == E_FAIL || hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2884     if (SUCCEEDED(hr))
2885         ID3D12RootSignature_Release(root_signature);
2886     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_GEOMETRY;
2887     hr = create_root_signature(device, &root_signature_desc, &root_signature);
2888     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
2889     refcount = ID3D12RootSignature_Release(root_signature);
2890     ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
2891 
2892     refcount = ID3D12Device_Release(device);
2893     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
2894 }
2895 
test_root_signature_limits(void)2896 static void test_root_signature_limits(void)
2897 {
2898     D3D12_DESCRIPTOR_RANGE descriptor_ranges[D3D12_MAX_ROOT_COST + 1];
2899     D3D12_ROOT_PARAMETER root_parameters[D3D12_MAX_ROOT_COST + 1];
2900     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
2901     ID3D12RootSignature *root_signature;
2902     ID3D12Device *device;
2903     ULONG refcount;
2904     unsigned int i;
2905     HRESULT hr;
2906 
2907     if (!(device = create_device()))
2908     {
2909         skip("Failed to create device.\n");
2910         return;
2911     }
2912 
2913     /* A descriptor table costs 1 DWORD. */
2914     for (i = 0; i < ARRAY_SIZE(root_parameters); ++i)
2915     {
2916         descriptor_ranges[i].RangeType = i % 2
2917                 ? D3D12_DESCRIPTOR_RANGE_TYPE_SRV : D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
2918         descriptor_ranges[i].NumDescriptors = 1;
2919         descriptor_ranges[i].BaseShaderRegister = i / 2;
2920         descriptor_ranges[i].RegisterSpace = 0;
2921         descriptor_ranges[i].OffsetInDescriptorsFromTableStart = 0;
2922         root_parameters[i].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
2923         root_parameters[i].DescriptorTable.NumDescriptorRanges = 1;
2924         root_parameters[i].DescriptorTable.pDescriptorRanges = &descriptor_ranges[i];
2925         root_parameters[i].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
2926     }
2927 
2928     root_signature_desc.NumParameters = D3D12_MAX_ROOT_COST;
2929     root_signature_desc.pParameters = root_parameters;
2930     root_signature_desc.NumStaticSamplers = 0;
2931     root_signature_desc.pStaticSamplers = NULL;
2932     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
2933     hr = create_root_signature(device, &root_signature_desc, &root_signature);
2934     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
2935     ID3D12RootSignature_Release(root_signature);
2936 
2937     root_signature_desc.NumParameters = D3D12_MAX_ROOT_COST + 1;
2938     hr = create_root_signature(device, &root_signature_desc, &root_signature);
2939     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
2940 
2941     refcount = ID3D12Device_Release(device);
2942     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
2943 }
2944 
test_create_compute_pipeline_state(void)2945 static void test_create_compute_pipeline_state(void)
2946 {
2947     D3D12_COMPUTE_PIPELINE_STATE_DESC pipeline_state_desc;
2948     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
2949     ID3D12RootSignature *root_signature;
2950     ID3D12PipelineState *pipeline_state;
2951     ID3D12Device *device, *tmp_device;
2952     ULONG refcount;
2953     HRESULT hr;
2954 
2955     static const DWORD dxbc_code[] =
2956     {
2957 #if 0
2958         [numthreads(1, 1, 1)]
2959         void main() { }
2960 #endif
2961         0x43425844, 0x1acc3ad0, 0x71c7b057, 0xc72c4306, 0xf432cb57, 0x00000001, 0x00000074, 0x00000003,
2962         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
2963         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000020, 0x00050050, 0x00000008, 0x0100086a,
2964         0x0400009b, 0x00000001, 0x00000001, 0x00000001, 0x0100003e,
2965     };
2966 
2967     if (!(device = create_device()))
2968     {
2969         skip("Failed to create device.\n");
2970         return;
2971     }
2972 
2973     root_signature_desc.NumParameters = 0;
2974     root_signature_desc.pParameters = NULL;
2975     root_signature_desc.NumStaticSamplers = 0;
2976     root_signature_desc.pStaticSamplers = NULL;
2977     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
2978     hr = create_root_signature(device, &root_signature_desc, &root_signature);
2979     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
2980 
2981     refcount = get_refcount(device);
2982     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2983 
2984     memset(&pipeline_state_desc, 0, sizeof(pipeline_state_desc));
2985     pipeline_state_desc.pRootSignature = root_signature;
2986     pipeline_state_desc.CS = shader_bytecode(dxbc_code, sizeof(dxbc_code));
2987     pipeline_state_desc.NodeMask = 0;
2988     pipeline_state_desc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
2989 
2990     hr = ID3D12Device_CreateComputePipelineState(device, &pipeline_state_desc,
2991             &IID_ID3D12PipelineState, (void **)&pipeline_state);
2992     ok(hr == S_OK, "Failed to create compute pipeline, hr %#x.\n", hr);
2993 
2994     refcount = get_refcount(root_signature);
2995     ok(refcount == 1, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2996 
2997     refcount = get_refcount(device);
2998     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
2999     hr = ID3D12PipelineState_GetDevice(pipeline_state, &IID_ID3D12Device, (void **)&tmp_device);
3000     ok(hr == S_OK, "Failed to get device, hr %#x.\n", hr);
3001     refcount = get_refcount(device);
3002     ok(refcount == 4, "Got unexpected refcount %u.\n", (unsigned int)refcount);
3003     refcount = ID3D12Device_Release(tmp_device);
3004     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
3005 
3006     check_interface(pipeline_state, &IID_ID3D12Object, true);
3007     check_interface(pipeline_state, &IID_ID3D12DeviceChild, true);
3008     check_interface(pipeline_state, &IID_ID3D12Pageable, true);
3009     check_interface(pipeline_state, &IID_ID3D12PipelineState, true);
3010 
3011     refcount = ID3D12PipelineState_Release(pipeline_state);
3012     ok(!refcount, "ID3D12PipelineState has %u references left.\n", (unsigned int)refcount);
3013     refcount = ID3D12RootSignature_Release(root_signature);
3014     ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
3015 
3016     refcount = ID3D12Device_Release(device);
3017     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
3018 }
3019 
test_create_graphics_pipeline_state(void)3020 static void test_create_graphics_pipeline_state(void)
3021 {
3022     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
3023     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
3024     ID3D12RootSignature *root_signature;
3025     ID3D12PipelineState *pipeline_state;
3026     ID3D12Device *device, *tmp_device;
3027     D3D12_BLEND_DESC *blend;
3028     ULONG refcount;
3029     unsigned int i;
3030     HRESULT hr;
3031 
3032     static const D3D12_SO_DECLARATION_ENTRY so_declaration[] =
3033     {
3034         {0, "SV_Position", 0, 0, 4, 0},
3035     };
3036     static const unsigned int strides[] = {16};
3037 
3038     if (!(device = create_device()))
3039     {
3040         skip("Failed to create device.\n");
3041         return;
3042     }
3043 
3044     root_signature_desc.NumParameters = 0;
3045     root_signature_desc.pParameters = NULL;
3046     root_signature_desc.NumStaticSamplers = 0;
3047     root_signature_desc.pStaticSamplers = NULL;
3048     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
3049     hr = create_root_signature(device, &root_signature_desc, &root_signature);
3050     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
3051 
3052     refcount = get_refcount(device);
3053     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
3054 
3055     init_pipeline_state_desc(&pso_desc, root_signature, DXGI_FORMAT_R8G8B8A8_UNORM, NULL, NULL, NULL);
3056     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
3057             &IID_ID3D12PipelineState, (void **)&pipeline_state);
3058     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
3059 
3060     refcount = get_refcount(root_signature);
3061     ok(refcount == 1, "Got unexpected refcount %u.\n", (unsigned int)refcount);
3062 
3063     refcount = get_refcount(device);
3064     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
3065     hr = ID3D12PipelineState_GetDevice(pipeline_state, &IID_ID3D12Device, (void **)&tmp_device);
3066     ok(hr == S_OK, "Failed to get device, hr %#x.\n", hr);
3067     refcount = get_refcount(device);
3068     ok(refcount == 4, "Got unexpected refcount %u.\n", (unsigned int)refcount);
3069     refcount = ID3D12Device_Release(tmp_device);
3070     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
3071 
3072     check_interface(pipeline_state, &IID_ID3D12Object, true);
3073     check_interface(pipeline_state, &IID_ID3D12DeviceChild, true);
3074     check_interface(pipeline_state, &IID_ID3D12Pageable, true);
3075     check_interface(pipeline_state, &IID_ID3D12PipelineState, true);
3076 
3077     refcount = ID3D12PipelineState_Release(pipeline_state);
3078     ok(!refcount, "ID3D12PipelineState has %u references left.\n", (unsigned int)refcount);
3079 
3080     blend = &pso_desc.BlendState;
3081     blend->IndependentBlendEnable = false;
3082     blend->RenderTarget[0].BlendEnable = true;
3083     blend->RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_COLOR;
3084     blend->RenderTarget[0].DestBlend = D3D12_BLEND_DEST_COLOR;
3085     blend->RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
3086     blend->RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA;
3087     blend->RenderTarget[0].DestBlendAlpha = D3D12_BLEND_DEST_ALPHA;
3088     blend->RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
3089     blend->RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
3090     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
3091             &IID_ID3D12PipelineState, (void **)&pipeline_state);
3092     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
3093     ID3D12PipelineState_Release(pipeline_state);
3094 
3095     /* Only one of BlendEnable or LogicOpEnable can be set to true. */
3096     blend->IndependentBlendEnable = false;
3097     blend->RenderTarget[0].BlendEnable = true;
3098     blend->RenderTarget[0].LogicOpEnable = true;
3099     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
3100             &IID_ID3D12PipelineState, (void **)&pipeline_state);
3101     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
3102     pso_desc.RTVFormats[0] = DXGI_FORMAT_R32_UINT;
3103     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
3104             &IID_ID3D12PipelineState, (void **)&pipeline_state);
3105     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
3106 
3107     blend->IndependentBlendEnable = false;
3108     blend->RenderTarget[0].BlendEnable = false;
3109     blend->RenderTarget[0].LogicOpEnable = true;
3110     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
3111             &IID_ID3D12PipelineState, (void **)&pipeline_state);
3112     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
3113     ID3D12PipelineState_Release(pipeline_state);
3114 
3115     /* IndependentBlendEnable must be set to false when logic operations are enabled. */
3116     blend->IndependentBlendEnable = true;
3117     blend->RenderTarget[0].LogicOpEnable = true;
3118     for (i = 1; i < ARRAY_SIZE(blend->RenderTarget); ++i)
3119         blend->RenderTarget[i] = blend->RenderTarget[0];
3120     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
3121             &IID_ID3D12PipelineState, (void **)&pipeline_state);
3122     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
3123 
3124     /* DSVFormat = DXGI_FORMAT_UNKNOWN */
3125     memset(blend, 0, sizeof(*blend));
3126     pso_desc.DSVFormat = DXGI_FORMAT_UNKNOWN;
3127     pso_desc.DepthStencilState.DepthEnable = true;
3128     pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
3129     pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
3130     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
3131             &IID_ID3D12PipelineState, (void **)&pipeline_state);
3132     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3133     ID3D12PipelineState_Release(pipeline_state);
3134 
3135     /* Invalid DSVFormat */
3136     pso_desc.DSVFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
3137     pso_desc.DepthStencilState.DepthEnable = true;
3138     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
3139             &IID_ID3D12PipelineState, (void **)&pipeline_state);
3140     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3141     ID3D12PipelineState_Release(pipeline_state);
3142 
3143     /* Inactive render targets formats must be set to DXGI_FORMAT_UNKNOWN. */
3144     init_pipeline_state_desc(&pso_desc, root_signature, DXGI_FORMAT_R8G8B8A8_UNORM, NULL, NULL, NULL);
3145     pso_desc.RTVFormats[1] = DXGI_FORMAT_R8G8B8A8_UNORM;
3146     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
3147             &IID_ID3D12PipelineState, (void **)&pipeline_state);
3148     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
3149 
3150     /* Stream output without D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT. */
3151     init_pipeline_state_desc(&pso_desc, root_signature, DXGI_FORMAT_R8G8B8A8_UNORM, NULL, NULL, NULL);
3152     pso_desc.StreamOutput.NumEntries = ARRAY_SIZE(so_declaration);
3153     pso_desc.StreamOutput.pSODeclaration = so_declaration;
3154     pso_desc.StreamOutput.pBufferStrides = strides;
3155     pso_desc.StreamOutput.NumStrides = ARRAY_SIZE(strides);
3156     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
3157             &IID_ID3D12PipelineState, (void **)&pipeline_state);
3158     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
3159 
3160     refcount = ID3D12RootSignature_Release(root_signature);
3161     ok(!refcount, "ID3D12RootSignature has %u references left.\n", (unsigned int)refcount);
3162     refcount = ID3D12Device_Release(device);
3163     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
3164 }
3165 
test_create_fence(void)3166 static void test_create_fence(void)
3167 {
3168     ID3D12Device *device, *tmp_device;
3169     ID3D12Fence *fence;
3170     ULONG refcount;
3171     uint64_t value;
3172     HRESULT hr;
3173 
3174     if (!(device = create_device()))
3175     {
3176         skip("Failed to create device.\n");
3177         return;
3178     }
3179 
3180     hr = ID3D12Device_CreateFence(device, 0, D3D12_FENCE_FLAG_NONE,
3181             &IID_ID3D12Fence, (void **)&fence);
3182     ok(SUCCEEDED(hr), "Failed to create fence, hr %#x.\n", hr);
3183 
3184     refcount = get_refcount(device);
3185     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
3186     hr = ID3D12Fence_GetDevice(fence, &IID_ID3D12Device, (void **)&tmp_device);
3187     ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
3188     refcount = get_refcount(device);
3189     ok(refcount == 3, "Got unexpected refcount %u.\n", (unsigned int)refcount);
3190     refcount = ID3D12Device_Release(tmp_device);
3191     ok(refcount == 2, "Got unexpected refcount %u.\n", (unsigned int)refcount);
3192 
3193     check_interface(fence, &IID_ID3D12Object, true);
3194     check_interface(fence, &IID_ID3D12DeviceChild, true);
3195     check_interface(fence, &IID_ID3D12Pageable, true);
3196     check_interface(fence, &IID_ID3D12Fence, true);
3197 
3198     value = ID3D12Fence_GetCompletedValue(fence);
3199     ok(value == 0, "Got unexpected value %"PRIu64".\n", value);
3200 
3201     refcount = ID3D12Fence_Release(fence);
3202     ok(!refcount, "ID3D12Fence has %u references left.\n", (unsigned int)refcount);
3203 
3204     hr = ID3D12Device_CreateFence(device, 99, D3D12_FENCE_FLAG_NONE,
3205             &IID_ID3D12Fence, (void **)&fence);
3206     ok(SUCCEEDED(hr), "Failed to create fence, hr %#x.\n", hr);
3207     value = ID3D12Fence_GetCompletedValue(fence);
3208     ok(value == 99, "Got unexpected value %"PRIu64".\n", value);
3209     refcount = ID3D12Fence_Release(fence);
3210     ok(!refcount, "ID3D12Fence has %u references left.\n", (unsigned int)refcount);
3211 
3212     refcount = ID3D12Device_Release(device);
3213     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
3214 }
3215 
test_object_interface(void)3216 static void test_object_interface(void)
3217 {
3218     D3D12_DESCRIPTOR_HEAP_DESC descriptor_heap_desc;
3219     D3D12_QUERY_HEAP_DESC query_heap_desc;
3220     ID3D12RootSignature *root_signature;
3221     ULONG refcount, expected_refcount;
3222     ID3D12CommandAllocator *allocator;
3223     D3D12_HEAP_DESC heap_desc;
3224     IUnknown *test_object;
3225     ID3D12Device *device;
3226     ID3D12Object *object;
3227     IUnknown *unknown;
3228     unsigned int size;
3229     unsigned int i;
3230     IUnknown *ptr;
3231     HRESULT hr;
3232 
3233     static const GUID test_guid
3234             = {0xfdb37466, 0x428f, 0x4edf, {0xa3, 0x7f, 0x9b, 0x1d, 0xf4, 0x88, 0xc5, 0xfc}};
3235     static const GUID test_guid2
3236             = {0x2e5afac2, 0x87b5, 0x4c10, {0x9b, 0x4b, 0x89, 0xd7, 0xd1, 0x12, 0xe7, 0x2b}};
3237     static const DWORD data[] = {1, 2, 3, 4};
3238     static const WCHAR deadbeefW[] = {'d', 'e', 'a', 'd', 'b', 'e', 'e', 'f', 0};
3239     static const WCHAR emptyW[] = {0};
3240     static const GUID *tests[] =
3241     {
3242         &IID_ID3D12CommandAllocator,
3243         &IID_ID3D12CommandList,
3244         &IID_ID3D12CommandQueue,
3245         &IID_ID3D12CommandSignature,
3246         &IID_ID3D12DescriptorHeap,
3247         &IID_ID3D12Device,
3248         &IID_ID3D12Fence,
3249         &IID_ID3D12Heap,
3250         &IID_ID3D12PipelineState,
3251         &IID_ID3D12QueryHeap,
3252         &IID_ID3D12Resource,
3253         &IID_ID3D12RootSignature,
3254     };
3255 
3256     if (!(device = create_device()))
3257     {
3258         skip("Failed to create device.\n");
3259         return;
3260     }
3261 
3262     for (i = 0; i < ARRAY_SIZE(tests); ++i)
3263     {
3264         if (IsEqualGUID(tests[i], &IID_ID3D12CommandAllocator))
3265         {
3266             vkd3d_test_set_context("command allocator");
3267             hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
3268                     &IID_IUnknown, (void **)&unknown);
3269             ok(hr == S_OK, "Failed to create command allocator, hr %#x.\n", hr);
3270         }
3271         else if (IsEqualGUID(tests[i], &IID_ID3D12CommandList))
3272         {
3273             vkd3d_test_set_context("command list");
3274             hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
3275                     &IID_ID3D12CommandAllocator, (void **)&allocator);
3276             ok(hr == S_OK, "Failed to create command allocator, hr %#x.\n", hr);
3277             hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
3278                     allocator, NULL, &IID_IUnknown, (void **)&unknown);
3279             ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
3280             ID3D12CommandAllocator_Release(allocator);
3281         }
3282         else if (IsEqualGUID(tests[i], &IID_ID3D12CommandQueue))
3283         {
3284             vkd3d_test_set_context("command queue");
3285             unknown = (IUnknown *)create_command_queue(device,
3286                     D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
3287         }
3288         else if (IsEqualGUID(tests[i], &IID_ID3D12CommandSignature))
3289         {
3290             vkd3d_test_set_context("command signature");
3291             unknown = (IUnknown *)create_command_signature(device, D3D12_INDIRECT_ARGUMENT_TYPE_DRAW);
3292         }
3293         else if (IsEqualGUID(tests[i], &IID_ID3D12DescriptorHeap))
3294         {
3295             vkd3d_test_set_context("descriptor heap");
3296             descriptor_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
3297             descriptor_heap_desc.NumDescriptors = 16;
3298             descriptor_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
3299             descriptor_heap_desc.NodeMask = 0;
3300             hr = ID3D12Device_CreateDescriptorHeap(device, &descriptor_heap_desc,
3301                     &IID_ID3D12DescriptorHeap, (void **)&unknown);
3302             ok(hr == S_OK, "Failed to create descriptor heap, hr %#x.\n", hr);
3303         }
3304         else if (IsEqualGUID(tests[i], &IID_ID3D12Device))
3305         {
3306             vkd3d_test_set_context("device");
3307             unknown = (IUnknown *)create_device();
3308         }
3309         else if (IsEqualGUID(tests[i], &IID_ID3D12Fence))
3310         {
3311             vkd3d_test_set_context("fence");
3312             hr = ID3D12Device_CreateFence(device, 0, D3D12_FENCE_FLAG_NONE,
3313                     &IID_IUnknown, (void **)&unknown);
3314             ok(hr == S_OK, "Failed to create fence, hr %#x.\n", hr);
3315         }
3316         else if (IsEqualGUID(tests[i], &IID_ID3D12Heap))
3317         {
3318             vkd3d_test_set_context("heap");
3319             heap_desc.SizeInBytes = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
3320             memset(&heap_desc.Properties, 0, sizeof(heap_desc.Properties));
3321             heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT;
3322             heap_desc.Alignment = 0;
3323             heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES;
3324             hr = ID3D12Device_CreateHeap(device, &heap_desc, &IID_ID3D12Heap, (void **)&unknown);
3325             ok(hr == S_OK, "Failed to create heap, hr %#x.\n", hr);
3326         }
3327         else if (IsEqualGUID(tests[i], &IID_ID3D12PipelineState))
3328         {
3329             vkd3d_test_set_context("pipeline state");
3330             root_signature = create_empty_root_signature(device, 0);
3331             unknown = (IUnknown *)create_pipeline_state(device,
3332                     root_signature, DXGI_FORMAT_R8G8B8A8_UNORM, NULL, NULL, NULL);
3333             ID3D12RootSignature_Release(root_signature);
3334         }
3335         else if (IsEqualGUID(tests[i], &IID_ID3D12QueryHeap))
3336         {
3337             vkd3d_test_set_context("query heap");
3338             query_heap_desc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION;
3339             query_heap_desc.Count = 8;
3340             query_heap_desc.NodeMask = 0;
3341             hr = ID3D12Device_CreateQueryHeap(device, &query_heap_desc,
3342                     &IID_ID3D12QueryHeap, (void **)&unknown);
3343             ok(hr == S_OK, "Failed to create query heap, hr %#x.\n", hr);
3344         }
3345         else if (IsEqualGUID(tests[i], &IID_ID3D12Resource))
3346         {
3347             vkd3d_test_set_context("resource");
3348             unknown = (IUnknown *)create_readback_buffer(device, 512);
3349         }
3350         else if (IsEqualGUID(tests[i], &IID_ID3D12RootSignature))
3351         {
3352             vkd3d_test_set_context("root signature");
3353             unknown = (IUnknown *)create_empty_root_signature(device, 0);
3354         }
3355         else
3356         {
3357             unknown = NULL;
3358         }
3359 
3360         ok(unknown, "Unhandled object type %u.\n", i);
3361         object = NULL;
3362         hr = IUnknown_QueryInterface(unknown, &IID_ID3D12Object, (void **)&object);
3363         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3364         IUnknown_Release(unknown);
3365 
3366         hr = ID3D12Object_SetPrivateData(object, &test_guid, 0, NULL);
3367         ok(hr == S_FALSE, "Got unexpected hr %#x.\n", hr);
3368         hr = ID3D12Object_SetPrivateDataInterface(object, &test_guid, NULL);
3369         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3370         hr = ID3D12Object_SetPrivateData(object, &test_guid, ~0u, NULL);
3371         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3372         hr = ID3D12Object_SetPrivateData(object, &test_guid, ~0u, NULL);
3373         ok(hr == S_FALSE, "Got unexpected hr %#x.\n", hr);
3374 
3375         hr = ID3D12Object_SetPrivateDataInterface(object, &test_guid, NULL);
3376         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3377         size = sizeof(ptr) * 2;
3378         ptr = (IUnknown *)0xdeadbeef;
3379         hr = ID3D12Object_GetPrivateData(object, &test_guid, &size, &ptr);
3380         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3381         ok(!ptr, "Got unexpected pointer %p.\n", ptr);
3382         ok(size == sizeof(IUnknown *), "Got unexpected size %u.\n", size);
3383 
3384         hr = ID3D12Device_CreateFence(device, 0, D3D12_FENCE_FLAG_NONE,
3385                 &IID_ID3D12Fence, (void **)&test_object);
3386         ok(hr == S_OK, "Failed to create fence, hr %#x.\n", hr);
3387 
3388         refcount = get_refcount(test_object);
3389         hr = ID3D12Object_SetPrivateDataInterface(object, &test_guid, (IUnknown *)test_object);
3390         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3391         expected_refcount = refcount + 1;
3392         refcount = get_refcount(test_object);
3393         ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n",
3394                 (unsigned int)refcount, (unsigned int)expected_refcount);
3395         hr = ID3D12Object_SetPrivateDataInterface(object, &test_guid, (IUnknown *)test_object);
3396         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3397         refcount = get_refcount(test_object);
3398         ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n",
3399                 (unsigned int)refcount, (unsigned int)expected_refcount);
3400 
3401         hr = ID3D12Object_SetPrivateDataInterface(object, &test_guid, NULL);
3402         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3403         --expected_refcount;
3404         refcount = get_refcount(test_object);
3405         ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n",
3406                 (unsigned int)refcount, (unsigned int)expected_refcount);
3407 
3408         hr = ID3D12Object_SetPrivateDataInterface(object, &test_guid, (IUnknown *)test_object);
3409         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3410         size = sizeof(data);
3411         hr = ID3D12Object_SetPrivateData(object, &test_guid, size, data);
3412         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3413         refcount = get_refcount(test_object);
3414         ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n",
3415                 (unsigned int)refcount, (unsigned int)expected_refcount);
3416         hr = ID3D12Object_SetPrivateData(object, &test_guid, 42, NULL);
3417         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3418         hr = ID3D12Object_SetPrivateData(object, &test_guid, 42, NULL);
3419         ok(hr == S_FALSE, "Got unexpected hr %#x.\n", hr);
3420 
3421         hr = ID3D12Object_SetPrivateDataInterface(object, &test_guid, (IUnknown *)test_object);
3422         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3423         ++expected_refcount;
3424         size = 2 * sizeof(ptr);
3425         ptr = NULL;
3426         hr = ID3D12Object_GetPrivateData(object, &test_guid, &size, &ptr);
3427         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3428         ok(size == sizeof(test_object), "Got unexpected size %u.\n", size);
3429         ++expected_refcount;
3430         refcount = get_refcount(test_object);
3431         ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n",
3432                 (unsigned int)refcount, (unsigned int)expected_refcount);
3433         IUnknown_Release(ptr);
3434         --expected_refcount;
3435 
3436         ptr = (IUnknown *)0xdeadbeef;
3437         size = 1;
3438         hr = ID3D12Object_GetPrivateData(object, &test_guid, &size, NULL);
3439         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3440         ok(size == sizeof(ptr), "Got unexpected size %u.\n", size);
3441         size = 2 * sizeof(ptr);
3442         hr = ID3D12Object_GetPrivateData(object, &test_guid, &size, NULL);
3443         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3444         ok(size == sizeof(ptr), "Got unexpected size %u.\n", size);
3445         refcount = get_refcount(test_object);
3446         ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n",
3447                 (unsigned int)refcount, (unsigned int)expected_refcount);
3448 
3449         size = 1;
3450         hr = ID3D12Object_GetPrivateData(object, &test_guid, &size, &ptr);
3451         ok(hr == DXGI_ERROR_MORE_DATA, "Got unexpected hr %#x.\n", hr);
3452         ok(size == sizeof(object), "Got unexpected size %u.\n", size);
3453         ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
3454         size = 1;
3455         hr = ID3D12Object_GetPrivateData(object, &test_guid2, &size, &ptr);
3456         ok(hr == DXGI_ERROR_NOT_FOUND, "Got unexpected hr %#x.\n", hr);
3457         ok(!size, "Got unexpected size %u.\n", size);
3458         ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
3459 
3460         if (IsEqualGUID(tests[i], &IID_ID3D12Device))
3461         {
3462             hr = ID3D12Object_SetPrivateDataInterface(object, &test_guid, NULL);
3463             ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3464         }
3465 
3466         hr = ID3D12Object_SetName(object, emptyW);
3467         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3468 
3469         hr = ID3D12Object_SetName(object, deadbeefW);
3470         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3471 
3472         ID3D12Object_Release(object);
3473 
3474         refcount = IUnknown_Release(test_object);
3475         ok(!refcount, "Test object has %u references left.\n", (unsigned int)refcount);
3476 
3477         vkd3d_test_set_context(NULL);
3478     }
3479 
3480     refcount = ID3D12Device_Release(device);
3481     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
3482 }
3483 
3484 struct private_data
3485 {
3486     ID3D12Object *object;
3487     GUID guid;
3488     unsigned int value;
3489 };
3490 
private_data_thread_main(void * untyped_data)3491 static void private_data_thread_main(void *untyped_data)
3492 {
3493     struct private_data *data = untyped_data;
3494     unsigned int i;
3495     HRESULT hr;
3496 
3497     hr = ID3D12Object_SetPrivateData(data->object, &data->guid, sizeof(data->value), &data->value);
3498     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3499 
3500     for (i = 0; i < 100000; ++i)
3501     {
3502         hr = ID3D12Object_SetPrivateData(data->object, &data->guid, 0, NULL);
3503         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3504         hr = ID3D12Object_SetPrivateData(data->object, &data->guid, sizeof(data->value), &data->value);
3505         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3506     }
3507 }
3508 
3509 struct private_data_interface
3510 {
3511     ID3D12Object *object;
3512     GUID guid;
3513     IUnknown *iface;
3514 };
3515 
private_data_interface_thread_main(void * untyped_data)3516 static void private_data_interface_thread_main(void *untyped_data)
3517 {
3518     struct private_data_interface *data = untyped_data;
3519     unsigned int i;
3520     HRESULT hr;
3521 
3522     for (i = 0; i < 100000; ++i)
3523     {
3524         hr = ID3D12Object_SetPrivateDataInterface(data->object, &data->guid, data->iface);
3525         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3526         hr = ID3D12Object_SetPrivateDataInterface(data->object, &data->guid, NULL);
3527         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3528         hr = ID3D12Object_SetPrivateDataInterface(data->object, &data->guid, data->iface);
3529         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3530     }
3531 }
3532 
test_multithread_private_data(void)3533 static void test_multithread_private_data(void)
3534 {
3535     static const GUID guid = {0xfdb37466, 0x428f, 0x4edf, {0xa3, 0x7f, 0x9b, 0x1d, 0xf4, 0x88, 0xc5, 0x00}};
3536     struct private_data_interface private_data_interface[4];
3537     HANDLE private_data_interface_thread[4];
3538     struct private_data private_data[4];
3539     ID3D12RootSignature *root_signature;
3540     HANDLE private_data_thread[4];
3541     IUnknown *test_object, *unk;
3542     ID3D12Device *device;
3543     ID3D12Object *object;
3544     unsigned int value;
3545     unsigned int size;
3546     unsigned int id;
3547     unsigned int i;
3548     ULONG refcount;
3549     HRESULT hr;
3550 
3551     if (!(device = create_device()))
3552     {
3553         skip("Failed to create device.\n");
3554         return;
3555     }
3556 
3557     root_signature = create_empty_root_signature(device,
3558             D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
3559     hr = ID3D12RootSignature_QueryInterface(root_signature, &IID_ID3D12Object, (void **)&object);
3560     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3561     ID3D12RootSignature_Release(root_signature);
3562 
3563     hr = ID3D12Device_CreateFence(device, 0, D3D12_FENCE_FLAG_NONE,
3564             &IID_ID3D12Fence, (void **)&test_object);
3565     ok(hr == S_OK, "Failed to create fence, hr %#x.\n", hr);
3566 
3567     for (i = 0, id = 1; i < ARRAY_SIZE(private_data_interface); ++i, ++id)
3568     {
3569         private_data_interface[i].object = object;
3570         private_data_interface[i].guid = guid;
3571         private_data_interface[i].guid.Data4[7] = id;
3572 
3573         hr = ID3D12Device_CreateFence(device, 0, D3D12_FENCE_FLAG_NONE,
3574                 &IID_ID3D12Fence, (void **)&private_data_interface[i].iface);
3575         ok(hr == S_OK, "Failed to create fence %u, hr %#x.\n", i, hr);
3576     }
3577     for (i = 0; i < ARRAY_SIZE(private_data); ++i, ++id)
3578     {
3579         private_data[i].object = object;
3580         private_data[i].guid = guid;
3581         private_data[i].guid.Data4[7] = id;
3582         private_data[i].value = id;
3583     }
3584 
3585     for (i = 0; i < 4; ++i)
3586     {
3587         private_data_interface_thread[i] = create_thread(private_data_interface_thread_main, &private_data_interface[i]);
3588         private_data_thread[i] = create_thread(private_data_thread_main, &private_data[i]);
3589     }
3590 
3591     for (i = 0; i < 100000; ++i)
3592     {
3593         hr = ID3D12Object_SetPrivateDataInterface(object, &guid, test_object);
3594         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3595         hr = ID3D12Object_SetPrivateDataInterface(object, &guid, NULL);
3596         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3597         hr = ID3D12Object_SetPrivateDataInterface(object, &guid, test_object);
3598         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3599     }
3600 
3601     for (i = 0; i < 4; ++i)
3602     {
3603         ok(join_thread(private_data_interface_thread[i]), "Failed to join thread %u.\n", i);
3604         ok(join_thread(private_data_thread[i]), "Failed to join thread %u.\n", i);
3605     }
3606 
3607     for (i = 0; i < ARRAY_SIZE(private_data_interface); ++i)
3608     {
3609         size = sizeof(unk);
3610         hr = ID3D12Object_GetPrivateData(object, &private_data_interface[i].guid, &size, &unk);
3611         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3612 
3613         ok(unk == private_data_interface[i].iface, "Got %p, expected %p.\n", unk, private_data_interface[i].iface);
3614         IUnknown_Release(unk);
3615         refcount = IUnknown_Release(private_data_interface[i].iface);
3616         ok(refcount == 1, "Got unexpected refcount %u.\n", (unsigned int)refcount);
3617     }
3618     for (i = 0; i < ARRAY_SIZE(private_data); ++i)
3619     {
3620         size = sizeof(value);
3621         hr = ID3D12Object_GetPrivateData(object, &private_data[i].guid, &size, &value);
3622         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3623 
3624         ok(value == private_data[i].value, "Got %u, expected %u.\n", value, private_data[i].value);
3625     }
3626 
3627     hr = ID3D12Object_SetPrivateDataInterface(object, &guid, NULL);
3628     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3629     refcount = IUnknown_Release(test_object);
3630     ok(!refcount, "Test object has %u references left.\n", (unsigned int)refcount);
3631     refcount = ID3D12Object_Release(object);
3632     ok(!refcount, "Object has %u references left.\n", (unsigned int)refcount);
3633     refcount = ID3D12Device_Release(device);
3634     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
3635 }
3636 
test_reset_command_allocator(void)3637 static void test_reset_command_allocator(void)
3638 {
3639     ID3D12CommandAllocator *command_allocator, *command_allocator2;
3640     ID3D12GraphicsCommandList *command_list, *command_list2;
3641     D3D12_COMMAND_QUEUE_DESC command_queue_desc;
3642     ID3D12CommandQueue *queue;
3643     ID3D12Device *device;
3644     ULONG refcount;
3645     HRESULT hr;
3646 
3647     if (!(device = create_device()))
3648     {
3649         skip("Failed to create device.\n");
3650         return;
3651     }
3652 
3653     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
3654             &IID_ID3D12CommandAllocator, (void **)&command_allocator);
3655     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
3656 
3657     hr = ID3D12CommandAllocator_Reset(command_allocator);
3658     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3659     hr = ID3D12CommandAllocator_Reset(command_allocator);
3660     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3661 
3662     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
3663             command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list);
3664     ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
3665 
3666     hr = ID3D12CommandAllocator_Reset(command_allocator);
3667     ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
3668     hr = ID3D12CommandAllocator_Reset(command_allocator);
3669     ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
3670 
3671     hr = ID3D12GraphicsCommandList_Close(command_list);
3672     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
3673 
3674     hr = ID3D12CommandAllocator_Reset(command_allocator);
3675     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3676     hr = ID3D12CommandAllocator_Reset(command_allocator);
3677     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3678 
3679     hr = ID3D12GraphicsCommandList_Reset(command_list, command_allocator, NULL);
3680     ok(SUCCEEDED(hr), "Failed to reset command list, hr %#x.\n", hr);
3681 
3682     hr = ID3D12CommandAllocator_Reset(command_allocator);
3683     ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
3684 
3685     hr = ID3D12GraphicsCommandList_Close(command_list);
3686     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
3687     hr = ID3D12GraphicsCommandList_Reset(command_list, command_allocator, NULL);
3688     ok(SUCCEEDED(hr), "Failed to reset command list, hr %#x.\n", hr);
3689 
3690     command_queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
3691     command_queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
3692     command_queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
3693     command_queue_desc.NodeMask = 0;
3694     hr = ID3D12Device_CreateCommandQueue(device, &command_queue_desc,
3695             &IID_ID3D12CommandQueue, (void **)&queue);
3696     ok(SUCCEEDED(hr), "Failed to create command queue, hr %#x.\n", hr);
3697     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
3698             &IID_ID3D12CommandAllocator, (void **)&command_allocator2);
3699     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
3700 
3701     uav_barrier(command_list, NULL);
3702     hr = ID3D12GraphicsCommandList_Close(command_list);
3703     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
3704     exec_command_list(queue, command_list);
3705 
3706     /* A command list can be reset when it is in use. */
3707     hr = ID3D12GraphicsCommandList_Reset(command_list, command_allocator2, NULL);
3708     ok(SUCCEEDED(hr), "Failed to reset command list, hr %#x.\n", hr);
3709     hr = ID3D12GraphicsCommandList_Close(command_list);
3710     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
3711 
3712     wait_queue_idle(device, queue);
3713     hr = ID3D12CommandAllocator_Reset(command_allocator);
3714     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3715     hr = ID3D12GraphicsCommandList_Reset(command_list, command_allocator, NULL);
3716     ok(SUCCEEDED(hr), "Failed to reset command list, hr %#x.\n", hr);
3717 
3718     uav_barrier(command_list, NULL);
3719     hr = ID3D12GraphicsCommandList_Close(command_list);
3720     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
3721     exec_command_list(queue, command_list);
3722 
3723     hr = ID3D12GraphicsCommandList_Reset(command_list, command_allocator, NULL);
3724     ok(SUCCEEDED(hr), "Failed to reset command list, hr %#x.\n", hr);
3725     hr = ID3D12GraphicsCommandList_Close(command_list);
3726     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
3727 
3728     wait_queue_idle(device, queue);
3729     hr = ID3D12CommandAllocator_Reset(command_allocator);
3730     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
3731     hr = ID3D12GraphicsCommandList_Reset(command_list, command_allocator, NULL);
3732     ok(SUCCEEDED(hr), "Failed to reset command list, hr %#x.\n", hr);
3733 
3734     /* A command allocator can be used with one command list at a time. */
3735     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
3736             command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list2);
3737     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
3738 
3739     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
3740             command_allocator2, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list2);
3741     ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
3742 
3743     hr = ID3D12GraphicsCommandList_Close(command_list2);
3744     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
3745     hr = ID3D12GraphicsCommandList_Reset(command_list2, command_allocator, NULL);
3746     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
3747     ID3D12GraphicsCommandList_Release(command_list2);
3748 
3749     /* A command allocator can be re-used after closing the command list. */
3750     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
3751             command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list2);
3752     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
3753     hr = ID3D12GraphicsCommandList_Close(command_list);
3754     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
3755     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
3756             command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list2);
3757     ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
3758 
3759     ID3D12CommandAllocator_Release(command_allocator);
3760     ID3D12CommandAllocator_Release(command_allocator2);
3761     ID3D12CommandQueue_Release(queue);
3762     ID3D12GraphicsCommandList_Release(command_list);
3763     ID3D12GraphicsCommandList_Release(command_list2);
3764     refcount = ID3D12Device_Release(device);
3765     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
3766 }
3767 
test_cpu_signal_fence(void)3768 static void test_cpu_signal_fence(void)
3769 {
3770     HANDLE event1, event2;
3771     ID3D12Device *device;
3772     unsigned int i, ret;
3773     ID3D12Fence *fence;
3774     ULONG refcount;
3775     uint64_t value;
3776     HRESULT hr;
3777 
3778     if (!(device = create_device()))
3779     {
3780         skip("Failed to create device.\n");
3781         return;
3782     }
3783 
3784     hr = ID3D12Device_CreateFence(device, 0, D3D12_FENCE_FLAG_NONE,
3785             &IID_ID3D12Fence, (void **)&fence);
3786     ok(SUCCEEDED(hr), "Failed to create fence, hr %#x.\n", hr);
3787 
3788     hr = ID3D12Fence_Signal(fence, 1);
3789     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3790     value = ID3D12Fence_GetCompletedValue(fence);
3791     ok(value == 1, "Got unexpected value %"PRIu64".\n", value);
3792 
3793     hr = ID3D12Fence_Signal(fence, 10);
3794     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3795     value = ID3D12Fence_GetCompletedValue(fence);
3796     ok(value == 10, "Got unexpected value %"PRIu64".\n", value);
3797 
3798     hr = ID3D12Fence_Signal(fence, 5);
3799     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3800     value = ID3D12Fence_GetCompletedValue(fence);
3801     ok(value == 5, "Got unexpected value %"PRIu64".\n", value);
3802 
3803     hr = ID3D12Fence_Signal(fence, 0);
3804     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3805     value = ID3D12Fence_GetCompletedValue(fence);
3806     ok(value == 0, "Got unexpected value %"PRIu64".\n", value);
3807 
3808     /* Basic tests with single event. */
3809     event1 = create_event();
3810     ok(event1, "Failed to create event.\n");
3811     ret = wait_event(event1, 0);
3812     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3813 
3814     hr = ID3D12Fence_SetEventOnCompletion(fence, 5, event1);
3815     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
3816     ret = wait_event(event1, 0);
3817     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3818     hr = ID3D12Fence_Signal(fence, 5);
3819     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3820     ret = wait_event(event1, 0);
3821     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
3822     ret = wait_event(event1, 0);
3823     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3824 
3825     hr = ID3D12Fence_SetEventOnCompletion(fence, 6, event1);
3826     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
3827     ret = wait_event(event1, 0);
3828     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3829     hr = ID3D12Fence_Signal(fence, 7);
3830     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3831     ret = wait_event(event1, 0);
3832     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
3833     ret = wait_event(event1, 0);
3834     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3835 
3836     hr = ID3D12Fence_Signal(fence, 10);
3837     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3838     ret = wait_event(event1, 0);
3839     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3840 
3841     /* Event is signaled immediately when value <= GetCompletedValue(). */
3842     ret = wait_event(event1, 0);
3843     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3844     for (i = 0; i <= ID3D12Fence_GetCompletedValue(fence); ++i)
3845     {
3846         hr = ID3D12Fence_SetEventOnCompletion(fence, i, event1);
3847         ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
3848         ret = wait_event(event1, 0);
3849         ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x for %u.\n", ret, i);
3850         ret = wait_event(event1, 0);
3851         ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x for %u.\n", ret, i);
3852     }
3853     hr = ID3D12Fence_SetEventOnCompletion(fence, i, event1);
3854     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
3855     ret = wait_event(event1, 0);
3856     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3857     hr = ID3D12Fence_Signal(fence, i);
3858     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3859     ret = wait_event(event1, 0);
3860     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
3861     ret = wait_event(event1, 0);
3862     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3863 
3864     /* Attach event to multiple values. */
3865     hr = ID3D12Fence_Signal(fence, 0);
3866     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3867     ret = wait_event(event1, 0);
3868     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3869 
3870     hr = ID3D12Fence_SetEventOnCompletion(fence, 3, event1);
3871     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
3872     hr = ID3D12Fence_SetEventOnCompletion(fence, 5, event1);
3873     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
3874     hr = ID3D12Fence_SetEventOnCompletion(fence, 9, event1);
3875     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
3876     hr = ID3D12Fence_SetEventOnCompletion(fence, 12, event1);
3877     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
3878     hr = ID3D12Fence_SetEventOnCompletion(fence, 12, event1);
3879     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
3880     ret = wait_event(event1, 0);
3881     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3882     for (i = 1; i < 13; ++i)
3883     {
3884         hr = ID3D12Fence_Signal(fence, i);
3885         ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3886         if (i == 3 || i == 5 || i == 9 || i == 12)
3887         {
3888             ret = wait_event(event1, 0);
3889             ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x for %u.\n", ret, i);
3890         }
3891         ret = wait_event(event1, 0);
3892         ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x for %u.\n", ret, i);
3893     }
3894 
3895     /* Tests with 2 events. */
3896     hr = ID3D12Fence_Signal(fence, 0);
3897     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3898     value = ID3D12Fence_GetCompletedValue(fence);
3899     ok(value == 0, "Got unexpected value %"PRIu64".\n", value);
3900 
3901     event2 = create_event();
3902     ok(event2, "Failed to create event.\n");
3903 
3904     ret = wait_event(event1, 0);
3905     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3906     ret = wait_event(event2, 0);
3907     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3908     hr = ID3D12Fence_SetEventOnCompletion(fence, 100, event1);
3909     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
3910     hr = ID3D12Fence_SetEventOnCompletion(fence, ~(uint64_t)0, event2);
3911     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
3912 
3913     hr = ID3D12Fence_Signal(fence, 50);
3914     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3915     ret = wait_event(event1, 0);
3916     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3917     ret = wait_event(event2, 0);
3918     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3919 
3920     hr = ID3D12Fence_Signal(fence, 99);
3921     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3922     ret = wait_event(event1, 0);
3923     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3924     ret = wait_event(event2, 0);
3925     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3926 
3927     hr = ID3D12Fence_Signal(fence, 100);
3928     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3929     ret = wait_event(event1, 0);
3930     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
3931     ret = wait_event(event1, 0);
3932     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3933     ret = wait_event(event2, 0);
3934     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3935 
3936     hr = ID3D12Fence_Signal(fence, 101);
3937     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3938     ret = wait_event(event1, 0);
3939     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3940     ret = wait_event(event2, 0);
3941     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3942 
3943     hr = ID3D12Fence_Signal(fence, 0);
3944     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3945     ret = wait_event(event1, 0);
3946     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3947     ret = wait_event(event2, 0);
3948     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3949 
3950     hr = ID3D12Fence_Signal(fence, 100);
3951     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3952     ret = wait_event(event1, 0);
3953     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3954     ret = wait_event(event2, 0);
3955     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3956 
3957     hr = ID3D12Fence_Signal(fence, ~(uint64_t)0);
3958     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3959     ret = wait_event(event1, 0);
3960     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3961     ret = wait_event(event2, 0);
3962     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
3963     ret = wait_event(event2, 0);
3964     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3965 
3966     hr = ID3D12Fence_Signal(fence, ~(uint64_t)0);
3967     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3968     ret = wait_event(event1, 0);
3969     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3970     ret = wait_event(event2, 0);
3971     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3972     hr = ID3D12Fence_Signal(fence, 0);
3973     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3974     ret = wait_event(event1, 0);
3975     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3976     ret = wait_event(event2, 0);
3977     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3978 
3979     /* Attach two events to the same value. */
3980     hr = ID3D12Fence_Signal(fence, 0);
3981     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3982     ret = wait_event(event1, 0);
3983     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3984     ret = wait_event(event2, 0);
3985     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3986 
3987     hr = ID3D12Fence_SetEventOnCompletion(fence, 1, event1);
3988     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
3989     hr = ID3D12Fence_SetEventOnCompletion(fence, 1, event2);
3990     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
3991     ret = wait_event(event1, 0);
3992     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3993     ret = wait_event(event2, 0);
3994     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
3995     hr = ID3D12Fence_Signal(fence, 3);
3996     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
3997     ret = wait_event(event1, 0);
3998     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
3999     ret = wait_event(event2, 0);
4000     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
4001     ret = wait_event(event1, 0);
4002     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4003     ret = wait_event(event2, 0);
4004     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4005 
4006     /* Test passing signaled event. */
4007     hr = ID3D12Fence_Signal(fence, 20);
4008     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
4009     value = ID3D12Fence_GetCompletedValue(fence);
4010     ok(value == 20, "Got unexpected value %"PRIu64".\n", value);
4011     ret = wait_event(event1, 0);
4012     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4013 
4014     signal_event(event1);
4015     hr = ID3D12Fence_SetEventOnCompletion(fence, 30, event1);
4016     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
4017     ret = wait_event(event1, 0);
4018     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
4019     ret = wait_event(event1, 0);
4020     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4021 
4022     hr = ID3D12Fence_Signal(fence, 30);
4023     ok(SUCCEEDED(hr), "Failed to signal fence, hr %#x.\n", hr);
4024     ret = wait_event(event1, 0);
4025     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
4026     ret = wait_event(event1, 0);
4027     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4028 
4029     destroy_event(event1);
4030     destroy_event(event2);
4031 
4032     ID3D12Fence_Release(fence);
4033     refcount = ID3D12Device_Release(device);
4034     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
4035 }
4036 
test_gpu_signal_fence(void)4037 static void test_gpu_signal_fence(void)
4038 {
4039     ID3D12CommandQueue *queue;
4040     HANDLE event1, event2;
4041     ID3D12Device *device;
4042     unsigned int i, ret;
4043     ID3D12Fence *fence;
4044     ULONG refcount;
4045     uint64_t value;
4046     HRESULT hr;
4047 
4048     if (!(device = create_device()))
4049     {
4050         skip("Failed to create device.\n");
4051         return;
4052     }
4053 
4054     queue = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
4055 
4056     hr = ID3D12Device_CreateFence(device, 0, D3D12_FENCE_FLAG_NONE,
4057             &IID_ID3D12Fence, (void **)&fence);
4058     ok(hr == S_OK, "Failed to create fence, hr %#x.\n", hr);
4059 
4060     /* XXX: It seems that when a queue is idle a fence is signalled immediately
4061      * in D3D12. Vulkan implementations don't signal a fence immediately so
4062      * libvkd3d doesn't as well. In order to make this test reliable
4063      * wait_queue_idle() is inserted after every ID3D12CommandQueue_Signal(). */
4064     queue_signal(queue, fence, 10);
4065     wait_queue_idle(device, queue);
4066     value = ID3D12Fence_GetCompletedValue(fence);
4067     ok(value == 10, "Got unexpected value %"PRIu64".\n", value);
4068 
4069     queue_signal(queue, fence, 0);
4070     wait_queue_idle(device, queue);
4071     value = ID3D12Fence_GetCompletedValue(fence);
4072     ok(value == 0, "Got unexpected value %"PRIu64".\n", value);
4073 
4074     /* Basic tests with single event. */
4075     event1 = create_event();
4076     ok(event1, "Failed to create event.\n");
4077     ret = wait_event(event1, 0);
4078     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4079 
4080     hr = ID3D12Fence_SetEventOnCompletion(fence, 5, event1);
4081     ok(hr == S_OK, "Failed to set event on completion, hr %#x.\n", hr);
4082     ret = wait_event(event1, 0);
4083     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4084     queue_signal(queue, fence, 5);
4085     wait_queue_idle(device, queue);
4086     ret = wait_event(event1, 0);
4087     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
4088     ret = wait_event(event1, 0);
4089     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4090 
4091     hr = ID3D12Fence_SetEventOnCompletion(fence, 6, event1);
4092     ok(hr == S_OK, "Failed to set event on completion, hr %#x.\n", hr);
4093     ret = wait_event(event1, 0);
4094     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4095     queue_signal(queue, fence, 7);
4096     wait_queue_idle(device, queue);
4097     ret = wait_event(event1, 0);
4098     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
4099     ret = wait_event(event1, 0);
4100     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4101 
4102     queue_signal(queue, fence, 10);
4103     wait_queue_idle(device, queue);
4104     ret = wait_event(event1, 0);
4105     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4106 
4107     /* Attach one event to multiple values. */
4108     queue_signal(queue, fence, 0);
4109     wait_queue_idle(device, queue);
4110     ret = wait_event(event1, 0);
4111     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4112 
4113     hr = ID3D12Fence_SetEventOnCompletion(fence, 3, event1);
4114     ok(hr == S_OK, "Failed to set event on completion, hr %#x.\n", hr);
4115     hr = ID3D12Fence_SetEventOnCompletion(fence, 5, event1);
4116     ok(hr == S_OK, "Failed to set event on completion, hr %#x.\n", hr);
4117     hr = ID3D12Fence_SetEventOnCompletion(fence, 9, event1);
4118     ok(hr == S_OK, "Failed to set event on completion, hr %#x.\n", hr);
4119     hr = ID3D12Fence_SetEventOnCompletion(fence, 12, event1);
4120     ok(hr == S_OK, "Failed to set event on completion, hr %#x.\n", hr);
4121     hr = ID3D12Fence_SetEventOnCompletion(fence, 12, event1);
4122     ok(hr == S_OK, "Failed to set event on completion, hr %#x.\n", hr);
4123     ret = wait_event(event1, 0);
4124     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4125     for (i = 1; i < 13; ++i)
4126     {
4127         queue_signal(queue, fence, i);
4128         wait_queue_idle(device, queue);
4129         if (i == 3 || i == 5 || i == 9 || i == 12)
4130         {
4131             ret = wait_event(event1, 0);
4132             ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x for %u.\n", ret, i);
4133         }
4134         ret = wait_event(event1, 0);
4135         ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x for %u.\n", ret, i);
4136     }
4137 
4138     /* Tests with 2 events. */
4139     queue_signal(queue, fence, 0);
4140     wait_queue_idle(device, queue);
4141     value = ID3D12Fence_GetCompletedValue(fence);
4142     ok(value == 0, "Got unexpected value %"PRIu64".\n", value);
4143 
4144     event2 = create_event();
4145     ok(event2, "Failed to create event.\n");
4146 
4147     ret = wait_event(event1, 0);
4148     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4149     ret = wait_event(event2, 0);
4150     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4151     hr = ID3D12Fence_SetEventOnCompletion(fence, 100, event1);
4152     ok(hr == S_OK, "Failed to set event on completion, hr %#x.\n", hr);
4153     hr = ID3D12Fence_SetEventOnCompletion(fence, ~(uint64_t)0, event2);
4154     ok(hr == S_OK, "Failed to set event on completion, hr %#x.\n", hr);
4155 
4156     queue_signal(queue, fence, 50);
4157     wait_queue_idle(device, queue);
4158     ret = wait_event(event1, 0);
4159     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4160     ret = wait_event(event2, 0);
4161     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4162 
4163     queue_signal(queue, fence, 99);
4164     wait_queue_idle(device, queue);
4165     ret = wait_event(event1, 0);
4166     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4167     ret = wait_event(event2, 0);
4168     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4169 
4170     queue_signal(queue, fence, 100);
4171     wait_queue_idle(device, queue);
4172     ret = wait_event(event1, 0);
4173     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
4174     ret = wait_event(event1, 0);
4175     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4176     ret = wait_event(event2, 0);
4177     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4178 
4179     queue_signal(queue, fence, 101);
4180     wait_queue_idle(device, queue);
4181     ret = wait_event(event1, 0);
4182     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4183     ret = wait_event(event2, 0);
4184     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4185 
4186     queue_signal(queue, fence, 0);
4187     wait_queue_idle(device, queue);
4188     ret = wait_event(event1, 0);
4189     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4190     ret = wait_event(event2, 0);
4191     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4192 
4193     queue_signal(queue, fence, 100);
4194     wait_queue_idle(device, queue);
4195     ret = wait_event(event1, 0);
4196     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4197     ret = wait_event(event2, 0);
4198     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4199 
4200     queue_signal(queue, fence, ~(uint64_t)0);
4201     wait_queue_idle(device, queue);
4202     ret = wait_event(event1, 0);
4203     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4204     ret = wait_event(event2, 0);
4205     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
4206     ret = wait_event(event2, 0);
4207     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4208 
4209     queue_signal(queue, fence, ~(uint64_t)0);
4210     wait_queue_idle(device, queue);
4211     ret = wait_event(event1, 0);
4212     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4213     ret = wait_event(event2, 0);
4214     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4215     queue_signal(queue, fence, 0);
4216     wait_queue_idle(device, queue);
4217     ret = wait_event(event1, 0);
4218     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4219     ret = wait_event(event2, 0);
4220     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4221 
4222     /* Attach two events to the same value. */
4223     queue_signal(queue, fence, 0);
4224     wait_queue_idle(device, queue);
4225     ret = wait_event(event1, 0);
4226     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4227     ret = wait_event(event2, 0);
4228     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4229 
4230     hr = ID3D12Fence_SetEventOnCompletion(fence, 1, event1);
4231     ok(hr == S_OK, "Failed to set event on completion, hr %#x.\n", hr);
4232     hr = ID3D12Fence_SetEventOnCompletion(fence, 1, event2);
4233     ok(hr == S_OK, "Failed to set event on completion, hr %#x.\n", hr);
4234     ret = wait_event(event1, 0);
4235     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4236     ret = wait_event(event2, 0);
4237     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4238     queue_signal(queue, fence, 3);
4239     wait_queue_idle(device, queue);
4240     ret = wait_event(event1, 0);
4241     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
4242     ret = wait_event(event2, 0);
4243     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
4244     ret = wait_event(event1, 0);
4245     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4246     ret = wait_event(event2, 0);
4247     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
4248 
4249     wait_queue_idle(device, queue);
4250 
4251     destroy_event(event1);
4252     destroy_event(event2);
4253 
4254     ID3D12Fence_Release(fence);
4255     ID3D12CommandQueue_Release(queue);
4256     refcount = ID3D12Device_Release(device);
4257     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
4258 }
4259 
4260 struct multithread_fence_wait_data
4261 {
4262     HANDLE event;
4263     ID3D12Fence *fence;
4264     uint64_t value;
4265 };
4266 
fence_event_wait_main(void * untyped_data)4267 static void fence_event_wait_main(void *untyped_data)
4268 {
4269     struct multithread_fence_wait_data *data = untyped_data;
4270     unsigned int ret;
4271     HANDLE event;
4272     HRESULT hr;
4273 
4274     event = create_event();
4275     ok(event, "Failed to create event.\n");
4276 
4277     hr = ID3D12Fence_SetEventOnCompletion(data->fence, data->value, event);
4278     ok(SUCCEEDED(hr), "Failed to set event on completion, hr %#x.\n", hr);
4279 
4280     signal_event(data->event);
4281 
4282     ret = wait_event(event, INFINITE);
4283     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
4284 
4285     destroy_event(event);
4286 }
4287 
fence_busy_wait_main(void * untyped_data)4288 static void fence_busy_wait_main(void *untyped_data)
4289 {
4290     struct multithread_fence_wait_data *data = untyped_data;
4291 
4292     signal_event(data->event);
4293 
4294     while (ID3D12Fence_GetCompletedValue(data->fence) < data->value)
4295         ;
4296 }
4297 
test_multithread_fence_wait(void)4298 static void test_multithread_fence_wait(void)
4299 {
4300     struct multithread_fence_wait_data thread_data;
4301     ID3D12CommandQueue *queue;
4302     ID3D12Device *device;
4303     unsigned int ret;
4304     ULONG refcount;
4305     HANDLE thread;
4306     HRESULT hr;
4307 
4308     if (!(device = create_device()))
4309     {
4310         skip("Failed to create device.\n");
4311         return;
4312     }
4313 
4314     queue = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
4315 
4316     thread_data.event = create_event();
4317     thread_data.value = 0;
4318     ok(thread_data.event, "Failed to create event.\n");
4319     hr = ID3D12Device_CreateFence(device, thread_data.value, D3D12_FENCE_FLAG_NONE,
4320             &IID_ID3D12Fence, (void **)&thread_data.fence);
4321     ok(hr == S_OK, "Failed to create fence, hr %#x.\n", hr);
4322 
4323     /* Signal fence on host. */
4324     ++thread_data.value;
4325     thread = create_thread(fence_event_wait_main, &thread_data);
4326     ok(thread, "Failed to create thread.\n");
4327     ret = wait_event(thread_data.event, INFINITE);
4328     ok(ret == WAIT_OBJECT_0, "Failed to wait for thread start, return value %#x.\n", ret);
4329 
4330     hr = ID3D12Fence_Signal(thread_data.fence, thread_data.value);
4331     ok(hr == S_OK, "Failed to signal fence, hr %#x.\n", hr);
4332 
4333     ok(join_thread(thread), "Failed to join thread.\n");
4334 
4335     ++thread_data.value;
4336     thread = create_thread(fence_busy_wait_main, &thread_data);
4337     ok(thread, "Failed to create thread.\n");
4338     ret = wait_event(thread_data.event, INFINITE);
4339     ok(ret == WAIT_OBJECT_0, "Failed to wait for thread start, return value %#x.\n", ret);
4340 
4341     hr = ID3D12Fence_Signal(thread_data.fence, thread_data.value);
4342     ok(hr == S_OK, "Failed to signal fence, hr %#x.\n", hr);
4343 
4344     ok(join_thread(thread), "Failed to join thread.\n");
4345 
4346     /* Signal fence on device. */
4347     ++thread_data.value;
4348     thread = create_thread(fence_event_wait_main, &thread_data);
4349     ok(thread, "Failed to create thread.\n");
4350     ret = wait_event(thread_data.event, INFINITE);
4351     ok(ret == WAIT_OBJECT_0, "Failed to wait for thread start, return value %#x.\n", ret);
4352 
4353     queue_signal(queue, thread_data.fence, thread_data.value);
4354 
4355     ok(join_thread(thread), "Failed to join thread.\n");
4356 
4357     ++thread_data.value;
4358     thread = create_thread(fence_busy_wait_main, &thread_data);
4359     ok(thread, "Failed to create thread.\n");
4360     ret = wait_event(thread_data.event, INFINITE);
4361     ok(ret == WAIT_OBJECT_0, "Failed to wait for thread start, return value %#x.\n", ret);
4362 
4363     queue_signal(queue, thread_data.fence, thread_data.value);
4364 
4365     ok(join_thread(thread), "Failed to join thread.\n");
4366 
4367     destroy_event(thread_data.event);
4368     ID3D12Fence_Release(thread_data.fence);
4369     ID3D12CommandQueue_Release(queue);
4370     refcount = ID3D12Device_Release(device);
4371     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
4372 }
4373 
test_fence_values(void)4374 static void test_fence_values(void)
4375 {
4376     uint64_t value, next_value;
4377     ID3D12CommandQueue *queue;
4378     ID3D12Device *device;
4379     ID3D12Fence *fence;
4380     ULONG refcount;
4381     unsigned int i;
4382     HRESULT hr;
4383 
4384     if (!(device = create_device()))
4385     {
4386         skip("Failed to create device.\n");
4387         return;
4388     }
4389 
4390     queue = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
4391 
4392     next_value = (uint64_t)1 << 60;
4393     hr = ID3D12Device_CreateFence(device, next_value, D3D12_FENCE_FLAG_NONE, &IID_ID3D12Fence, (void **)&fence);
4394     ok(hr == S_OK, "Failed to create fence, hr %#x.\n", hr);
4395 
4396     value = ID3D12Fence_GetCompletedValue(fence);
4397     ok(value == next_value, "Got value %#"PRIx64", expected %#"PRIx64".\n", value, next_value);
4398 
4399     for (i = 0; i < 100; ++i)
4400     {
4401         ++next_value;
4402         queue_signal(queue, fence, next_value);
4403         wait_queue_idle(device, queue);
4404         value = ID3D12Fence_GetCompletedValue(fence);
4405         ok(value == next_value, "Got value %#"PRIx64", expected %#"PRIx64".\n", value, next_value);
4406     }
4407 
4408     for (i = 0; i < 100; ++i)
4409     {
4410         next_value += 10000;
4411         hr = ID3D12Fence_Signal(fence, next_value);
4412         ok(hr == S_OK, "Failed to signal fence, hr %#x.\n", hr);
4413         value = ID3D12Fence_GetCompletedValue(fence);
4414         ok(value == next_value, "Got value %#"PRIx64", expected %#"PRIx64".\n", value, next_value);
4415     }
4416 
4417     ID3D12Fence_Release(fence);
4418 
4419     hr = ID3D12Device_CreateFence(device, 0, D3D12_FENCE_FLAG_NONE, &IID_ID3D12Fence, (void **)&fence);
4420     ok(hr == S_OK, "Failed to create fence, hr %#x.\n", hr);
4421     next_value = (uint64_t)1 << 60;
4422     hr = ID3D12Fence_Signal(fence, next_value);
4423     ok(hr == S_OK, "Failed to signal fence, hr %#x.\n", hr);
4424     value = ID3D12Fence_GetCompletedValue(fence);
4425     ok(value == next_value, "Got value %#"PRIx64", expected %#"PRIx64".\n", value, next_value);
4426     next_value = 0;
4427     hr = ID3D12Fence_Signal(fence, next_value);
4428     ok(hr == S_OK, "Failed to signal fence, hr %#x.\n", hr);
4429     value = ID3D12Fence_GetCompletedValue(fence);
4430     ok(value == next_value, "Got value %#"PRIx64", expected %#"PRIx64".\n", value, next_value);
4431     ID3D12Fence_Release(fence);
4432 
4433     hr = ID3D12Device_CreateFence(device, 0, D3D12_FENCE_FLAG_NONE, &IID_ID3D12Fence, (void **)&fence);
4434     ok(hr == S_OK, "Failed to create fence, hr %#x.\n", hr);
4435     next_value = (uint64_t)1 << 60;
4436     queue_signal(queue, fence, next_value);
4437     wait_queue_idle(device, queue);
4438     value = ID3D12Fence_GetCompletedValue(fence);
4439     ok(value == next_value, "Got value %#"PRIx64", expected %#"PRIx64".\n", value, next_value);
4440     next_value = 0;
4441     queue_signal(queue, fence, next_value);
4442     wait_queue_idle(device, queue);
4443     value = ID3D12Fence_GetCompletedValue(fence);
4444     ok(value == next_value, "Got value %#"PRIx64", expected %#"PRIx64".\n", value, next_value);
4445     ID3D12Fence_Release(fence);
4446 
4447     ID3D12CommandQueue_Release(queue);
4448     refcount = ID3D12Device_Release(device);
4449     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
4450 }
4451 
test_clear_depth_stencil_view(void)4452 static void test_clear_depth_stencil_view(void)
4453 {
4454     static const float expected_values[] = {0.5f, 0.1f, 0.1f, 0.6, 1.0f, 0.5f};
4455     ID3D12GraphicsCommandList *command_list;
4456     D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc;
4457     struct depth_stencil_resource ds;
4458     unsigned int dsv_increment_size;
4459     D3D12_CLEAR_VALUE clear_value;
4460     struct test_context_desc desc;
4461     struct test_context context;
4462     ID3D12CommandQueue *queue;
4463     ID3D12Device *device;
4464     unsigned int i;
4465 
4466     memset(&desc, 0, sizeof(desc));
4467     desc.no_render_target = true;
4468     if (!init_test_context(&context, &desc))
4469         return;
4470     device = context.device;
4471     command_list = context.list;
4472     queue = context.queue;
4473 
4474     dsv_increment_size = ID3D12Device_GetDescriptorHandleIncrementSize(device,
4475             D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
4476     trace("DSV descriptor handle increment size: %u.\n", dsv_increment_size);
4477     ok(dsv_increment_size, "Got unexpected increment size %#x.\n", dsv_increment_size);
4478 
4479     clear_value.Format = DXGI_FORMAT_D32_FLOAT;
4480     clear_value.DepthStencil.Depth = 0.5f;
4481     clear_value.DepthStencil.Stencil = 0x3;
4482     init_depth_stencil(&ds, device, 32, 32, 1, 1, DXGI_FORMAT_D32_FLOAT, 0, &clear_value);
4483 
4484     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
4485             D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 0.75f, 0x7, 0, NULL);
4486     transition_resource_state(command_list, ds.texture,
4487             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
4488     check_sub_resource_float(ds.texture, 0, queue, command_list, 0.75f, 1);
4489 
4490     destroy_depth_stencil(&ds);
4491     reset_command_list(command_list, context.allocator);
4492     init_depth_stencil(&ds, device, 32, 32, 6, 1, DXGI_FORMAT_D32_FLOAT, 0, &clear_value);
4493 
4494     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
4495             D3D12_CLEAR_FLAG_DEPTH, expected_values[0], 0, 0, NULL);
4496     memset(&dsv_desc, 0, sizeof(dsv_desc));
4497     dsv_desc.Format = DXGI_FORMAT_D32_FLOAT;
4498     dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DARRAY;
4499     dsv_desc.Texture2DArray.FirstArraySlice = 1;
4500     dsv_desc.Texture2DArray.ArraySize = 2;
4501     ID3D12Device_CreateDepthStencilView(device, ds.texture, &dsv_desc, ds.dsv_handle);
4502     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
4503             D3D12_CLEAR_FLAG_DEPTH, expected_values[1], 0, 0, NULL);
4504     dsv_desc.Texture2DArray.FirstArraySlice = 3;
4505     dsv_desc.Texture2DArray.ArraySize = 1;
4506     ID3D12Device_CreateDepthStencilView(device, ds.texture, &dsv_desc, ds.dsv_handle);
4507     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
4508             D3D12_CLEAR_FLAG_DEPTH, expected_values[3], 0, 0, NULL);
4509     dsv_desc.Texture2DArray.FirstArraySlice = 4;
4510     ID3D12Device_CreateDepthStencilView(device, ds.texture, &dsv_desc, ds.dsv_handle);
4511     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
4512             D3D12_CLEAR_FLAG_DEPTH, expected_values[4], 0, 0, NULL);
4513 
4514     transition_resource_state(command_list, ds.texture,
4515             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
4516     for (i = 0; i < ARRAY_SIZE(expected_values); ++i)
4517     {
4518         check_sub_resource_float(ds.texture, i, queue, command_list, expected_values[i], 1);
4519         reset_command_list(command_list, context.allocator);
4520     }
4521 
4522     destroy_depth_stencil(&ds);
4523     destroy_test_context(&context);
4524 }
4525 
test_clear_render_target_view(void)4526 static void test_clear_render_target_view(void)
4527 {
4528     static const unsigned int array_expected_colors[] = {0xff00ff00, 0xff0000ff, 0xffff0000};
4529     static const struct vec4 array_colors[] =
4530     {
4531         {0.0f, 1.0f, 0.0f, 1.0f},
4532         {1.0f, 0.0f, 0.0f, 1.0f},
4533         {0.0f, 0.0f, 1.0f, 1.0f},
4534     };
4535     static const float negative_value[] = {1.0f, -1.0f, -0.5f, -2.0f};
4536     static const float color[] = {0.1f, 0.5f, 0.3f, 0.75f};
4537     static const float green[] = {0.0f, 1.0f, 0.0f, 1.0f};
4538     ID3D12GraphicsCommandList *command_list;
4539     D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle;
4540     D3D12_RENDER_TARGET_VIEW_DESC rtv_desc;
4541     D3D12_HEAP_PROPERTIES heap_properties;
4542     D3D12_RESOURCE_DESC resource_desc;
4543     unsigned int rtv_increment_size;
4544     ID3D12DescriptorHeap *rtv_heap;
4545     D3D12_CLEAR_VALUE clear_value;
4546     struct test_context_desc desc;
4547     struct resource_readback rb;
4548     struct test_context context;
4549     ID3D12CommandQueue *queue;
4550     ID3D12Resource *resource;
4551     ID3D12Device *device;
4552     unsigned int i;
4553     D3D12_BOX box;
4554     HRESULT hr;
4555 
4556     static const struct
4557     {
4558         const float *color;
4559         DXGI_FORMAT format;
4560         uint32_t result;
4561     }
4562     r8g8b8a8[] =
4563     {
4564         {color,          DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 0xbf95bc59},
4565 
4566         {green,          DXGI_FORMAT_R8G8B8A8_UNORM,      0xff00ff00},
4567         {color,          DXGI_FORMAT_R8G8B8A8_UNORM,      0xbf4c7f19},
4568 
4569         {green,          DXGI_FORMAT_R8G8B8A8_UINT,       0x01000100},
4570         {color,          DXGI_FORMAT_R8G8B8A8_UINT,       0x00000000},
4571         {negative_value, DXGI_FORMAT_R8G8B8A8_UINT,       0x00000001},
4572 
4573         {green,          DXGI_FORMAT_R8G8B8A8_SINT,       0x01000100},
4574         {color,          DXGI_FORMAT_R8G8B8A8_SINT,       0x00000000},
4575         {negative_value, DXGI_FORMAT_R8G8B8A8_SINT,       0xfe00ff01},
4576     };
4577     static const struct
4578     {
4579         const float *color;
4580         DXGI_FORMAT format;
4581         uint64_t result;
4582     }
4583     r16g16b16a16[] =
4584     {
4585         {green,          DXGI_FORMAT_R16G16B16A16_UNORM, 0xffff0000ffff0000},
4586 
4587         {green,          DXGI_FORMAT_R16G16B16A16_UINT,  0x0001000000010000},
4588         {color,          DXGI_FORMAT_R16G16B16A16_UINT,  0x0000000000000000},
4589         {negative_value, DXGI_FORMAT_R16G16B16A16_UINT,  0x0000000000000001},
4590 
4591         {green,          DXGI_FORMAT_R16G16B16A16_SINT,  0x0001000000010000},
4592         {color,          DXGI_FORMAT_R16G16B16A16_SINT,  0x0000000000000000},
4593         {negative_value, DXGI_FORMAT_R16G16B16A16_SINT,  0xfffe0000ffff0001},
4594     };
4595 
4596     STATIC_ASSERT(ARRAY_SIZE(array_colors) == ARRAY_SIZE(array_expected_colors));
4597 
4598     memset(&desc, 0, sizeof(desc));
4599     desc.no_render_target = true;
4600     if (!init_test_context(&context, &desc))
4601         return;
4602     device = context.device;
4603     command_list = context.list;
4604     queue = context.queue;
4605 
4606     rtv_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1);
4607 
4608     rtv_increment_size = ID3D12Device_GetDescriptorHandleIncrementSize(device,
4609             D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
4610     trace("RTV descriptor handle increment size: %u.\n", rtv_increment_size);
4611 
4612     rtv_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rtv_heap);
4613 
4614     memset(&heap_properties, 0, sizeof(heap_properties));
4615     heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
4616     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
4617     resource_desc.Alignment = 0;
4618     resource_desc.Width = 32;
4619     resource_desc.Height = 32;
4620     resource_desc.DepthOrArraySize = 1;
4621     resource_desc.MipLevels = 1;
4622     resource_desc.Format = DXGI_FORMAT_R8G8B8A8_TYPELESS;
4623     resource_desc.SampleDesc.Count = 1;
4624     resource_desc.SampleDesc.Quality = 0;
4625     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
4626     resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
4627     clear_value.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
4628     clear_value.Color[0] = 1.0f;
4629     clear_value.Color[1] = 0.0f;
4630     clear_value.Color[2] = 0.0f;
4631     clear_value.Color[3] = 1.0f;
4632     hr = ID3D12Device_CreateCommittedResource(device,
4633             &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
4634             D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
4635             &IID_ID3D12Resource, (void **)&resource);
4636     ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
4637 
4638     memset(&rtv_desc, 0, sizeof(rtv_desc));
4639     rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
4640 
4641     /* R8G8B8A8 */
4642     for (i = 0; i < ARRAY_SIZE(r8g8b8a8); ++i)
4643     {
4644         vkd3d_test_set_context("Test %u", i);
4645 
4646         rtv_desc.Format = r8g8b8a8[i].format;
4647         ID3D12Device_CreateRenderTargetView(device, resource, &rtv_desc, rtv_handle);
4648 
4649         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, r8g8b8a8[i].color, 0, NULL);
4650         transition_resource_state(command_list, resource,
4651                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
4652         check_sub_resource_uint(resource, 0, queue, command_list, r8g8b8a8[i].result, 2);
4653 
4654         reset_command_list(command_list, context.allocator);
4655         transition_resource_state(command_list, resource,
4656                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
4657     }
4658     vkd3d_test_set_context(NULL);
4659 
4660     /* R16G16B16A16 */
4661     hr = ID3D12GraphicsCommandList_Close(command_list);
4662     ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr);
4663     reset_command_list(command_list, context.allocator);
4664     ID3D12Resource_Release(resource);
4665     resource_desc.Format = DXGI_FORMAT_R16G16B16A16_TYPELESS;
4666     hr = ID3D12Device_CreateCommittedResource(device,
4667             &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
4668             D3D12_RESOURCE_STATE_RENDER_TARGET, NULL,
4669             &IID_ID3D12Resource, (void **)&resource);
4670     ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
4671 
4672     for (i = 0; i < ARRAY_SIZE(r16g16b16a16); ++i)
4673     {
4674         vkd3d_test_set_context("Test %u", i);
4675 
4676         rtv_desc.Format = r16g16b16a16[i].format;
4677         ID3D12Device_CreateRenderTargetView(device, resource, &rtv_desc, rtv_handle);
4678 
4679         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, r16g16b16a16[i].color, 0, NULL);
4680         transition_resource_state(command_list, resource,
4681                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
4682         check_sub_resource_uint64(resource, 0, queue, command_list, r16g16b16a16[i].result, 0);
4683 
4684         reset_command_list(command_list, context.allocator);
4685         transition_resource_state(command_list, resource,
4686                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
4687     }
4688     vkd3d_test_set_context(NULL);
4689 
4690     /* 2D array texture */
4691     hr = ID3D12GraphicsCommandList_Close(command_list);
4692     ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr);
4693     reset_command_list(command_list, context.allocator);
4694     ID3D12Resource_Release(resource);
4695     resource_desc.Format = DXGI_FORMAT_R8G8B8A8_TYPELESS;
4696     resource_desc.DepthOrArraySize = ARRAY_SIZE(array_colors);
4697     hr = ID3D12Device_CreateCommittedResource(device,
4698             &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
4699             D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
4700             &IID_ID3D12Resource, (void **)&resource);
4701     ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
4702 
4703     for (i = 0; i < ARRAY_SIZE(array_colors); ++i)
4704     {
4705         memset(&rtv_desc, 0, sizeof(rtv_desc));
4706         rtv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
4707         rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
4708         rtv_desc.Texture2DArray.FirstArraySlice = i;
4709         rtv_desc.Texture2DArray.ArraySize = 1;
4710 
4711         ID3D12Device_CreateRenderTargetView(device, resource, &rtv_desc, rtv_handle);
4712 
4713         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, &array_colors[i].x, 0, NULL);
4714     }
4715 
4716     transition_resource_state(command_list, resource,
4717             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
4718     for (i = 0; i < ARRAY_SIZE(array_expected_colors); ++i)
4719     {
4720         check_sub_resource_uint(resource, i, queue, command_list, array_expected_colors[i], 2);
4721         reset_command_list(command_list, context.allocator);
4722     }
4723 
4724     /* 2D multisample array texture */
4725     ID3D12Resource_Release(resource);
4726     resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
4727     resource_desc.SampleDesc.Count = 4;
4728     hr = ID3D12Device_CreateCommittedResource(device,
4729             &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
4730             D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
4731             &IID_ID3D12Resource, (void **)&resource);
4732     ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
4733 
4734     for (i = 0; i < ARRAY_SIZE(array_colors); ++i)
4735     {
4736         memset(&rtv_desc, 0, sizeof(rtv_desc));
4737         rtv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
4738         rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY;
4739         rtv_desc.Texture2DMSArray.FirstArraySlice = i;
4740         rtv_desc.Texture2DMSArray.ArraySize = 1;
4741 
4742         ID3D12Device_CreateRenderTargetView(device, resource, &rtv_desc, rtv_handle);
4743 
4744         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, &array_colors[i].x, 0, NULL);
4745     }
4746 
4747     transition_resource_state(command_list, resource,
4748             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
4749     for (i = 0; i < ARRAY_SIZE(array_expected_colors); ++i)
4750     {
4751         check_sub_resource_uint(resource, i, queue, command_list, array_expected_colors[i], 2);
4752         reset_command_list(command_list, context.allocator);
4753     }
4754 
4755     /* 3D texture */
4756     ID3D12Resource_Release(resource);
4757     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D;
4758     resource_desc.DepthOrArraySize = 32;
4759     resource_desc.MipLevels = 1;
4760     resource_desc.SampleDesc.Count = 1;
4761     hr = ID3D12Device_CreateCommittedResource(device,
4762             &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
4763             D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
4764             &IID_ID3D12Resource, (void **)&resource);
4765     ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
4766 
4767     ID3D12Device_CreateRenderTargetView(device, resource, NULL, rtv_handle);
4768 
4769     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, color, 0, NULL);
4770     transition_resource_state(command_list, resource,
4771             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
4772     check_sub_resource_uint(resource, 0, queue, command_list, 0xbf4c7f19, 2);
4773 
4774     memset(&rtv_desc, 0, sizeof(rtv_desc));
4775     rtv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
4776     rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D;
4777     rtv_desc.Texture3D.FirstWSlice = 2;
4778     rtv_desc.Texture3D.WSize = 2;
4779     ID3D12Device_CreateRenderTargetView(device, resource, &rtv_desc, rtv_handle);
4780 
4781     reset_command_list(command_list, context.allocator);
4782     transition_resource_state(command_list, resource,
4783             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
4784     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, green, 0, NULL);
4785     transition_resource_state(command_list, resource,
4786             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
4787     get_texture_readback_with_command_list(resource, 0, &rb, queue, command_list);
4788     set_box(&box, 0, 0, 0, 32, 32, 2);
4789     check_readback_data_uint(&rb, &box, 0xbf4c7f19, 1);
4790     set_box(&box, 0, 0, 2, 32, 32, 4);
4791     check_readback_data_uint(&rb, &box, 0xff00ff00, 1);
4792     set_box(&box, 0, 0, 4, 32, 32, 32);
4793     check_readback_data_uint(&rb, &box, 0xbf4c7f19, 1);
4794     release_resource_readback(&rb);
4795 
4796     ID3D12Resource_Release(resource);
4797     ID3D12DescriptorHeap_Release(rtv_heap);
4798     destroy_test_context(&context);
4799 }
4800 
test_clear_unordered_access_view_buffer(void)4801 static void test_clear_unordered_access_view_buffer(void)
4802 {
4803     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
4804     ID3D12DescriptorHeap *cpu_heap, *gpu_heap;
4805     ID3D12GraphicsCommandList *command_list;
4806     struct test_context_desc desc;
4807     struct test_context context;
4808     struct resource_readback rb;
4809     ID3D12CommandQueue *queue;
4810     D3D12_HEAP_DESC heap_desc;
4811     ID3D12Resource *buffer;
4812     ID3D12Device *device;
4813     UINT clear_value[4];
4814     unsigned int i, j;
4815     ID3D12Heap *heap;
4816     D3D12_BOX box;
4817     HRESULT hr;
4818 
4819 #define BUFFER_SIZE (1024 * 1024)
4820     static const struct
4821     {
4822         DXGI_FORMAT format;
4823         D3D12_BUFFER_UAV buffer_uav;
4824         unsigned int values[4];
4825         unsigned int expected;
4826         bool is_float;
4827         bool is_todo;
4828     }
4829     tests[] =
4830     {
4831         {DXGI_FORMAT_R32_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t),      0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4832                 {0, 0, 0, 0}, 0},
4833         {DXGI_FORMAT_R32_UINT, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4834                 {0, 0, 0, 0}, 0},
4835         {DXGI_FORMAT_R32_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t),      0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4836                 {1, 0, 0, 0}, 1},
4837         {DXGI_FORMAT_R32_UINT, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4838                 {2, 0, 0, 0}, 2},
4839         {DXGI_FORMAT_R32_UINT, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4840                 {3, 0, 0, 0}, 3},
4841         {DXGI_FORMAT_R32_UINT, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4842                 {4, 2, 3, 4}, 4},
4843         {DXGI_FORMAT_R32_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t) - 10, 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4844                 {5, 0, 0, 0}, 5},
4845 
4846         {DXGI_FORMAT_R32_TYPELESS, { 0, BUFFER_SIZE / sizeof(uint32_t),      0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
4847                 {0, 0, 0, 0}, 0},
4848         {DXGI_FORMAT_R32_TYPELESS, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
4849                 {0, 0, 0, 0}, 0},
4850         {DXGI_FORMAT_R32_TYPELESS, { 0, BUFFER_SIZE / sizeof(uint32_t),      0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
4851                 {6, 0, 0, 0}, 6},
4852         {DXGI_FORMAT_R32_TYPELESS, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
4853                 {7, 0, 0, 0}, 7},
4854         {DXGI_FORMAT_R32_TYPELESS, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
4855                 {8, 0, 0, 0}, 8},
4856         {DXGI_FORMAT_R32_TYPELESS, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
4857                 {9, 1, 1, 1}, 9},
4858         {DXGI_FORMAT_R32_TYPELESS, {64, BUFFER_SIZE / sizeof(uint32_t) - 64, 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
4859                 {~0u, 0, 0, 0}, ~0u},
4860         {DXGI_FORMAT_R32_TYPELESS, { 0, BUFFER_SIZE / sizeof(uint32_t) - 10, 0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
4861                 {10, 0, 0, 0}, 10},
4862         {DXGI_FORMAT_R32_TYPELESS, { 0, BUFFER_SIZE / sizeof(uint32_t) - 9,  0, 0, D3D12_BUFFER_UAV_FLAG_RAW},
4863                 {11, 0, 0, 0}, 11},
4864 
4865         {DXGI_FORMAT_R32_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4866                 {0, 0, 0, 0}, 0},
4867         {DXGI_FORMAT_R32_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4868                 {1, 0, 0, 0}, 1},
4869         {DXGI_FORMAT_R32_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4870                 {0x3f800000 /* 1.0f */, 0, 0, 0}, 0x3f800000 /* 1.0f */, true},
4871 
4872         {DXGI_FORMAT_R16G16_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4873                 {0x1234, 0xabcd, 0, 0}, 0xabcd1234},
4874         {DXGI_FORMAT_R16G16_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4875                 {0x10000, 0, 0, 0}, 0, false, true},
4876 
4877         {DXGI_FORMAT_R16G16_UNORM, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4878                 {0x1234, 0xabcd, 0, 0}, 0xabcd1234},
4879         {DXGI_FORMAT_R16G16_UNORM, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4880                 {0x3f000000 /* 0.5f */, 0x3f800000 /* 1.0f */, 0, 0}, 0xffff8000, true},
4881         {DXGI_FORMAT_R16G16_UNORM, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4882                 {0x40000000 /* 2.0f */, 0 /* 0.0f */, 0, 0}, 0x0000ffff, true},
4883         {DXGI_FORMAT_R16G16_UNORM, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4884                 {0xbf800000 /* -1.0f */, 0 /* 0.0f */, 0x3f000000 /* 1.0f */, 0x3f000000 /* 1.0f */}, 0, true},
4885 
4886         {DXGI_FORMAT_R16G16_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4887                 {0x1234, 0xabcd, 0, 0}, 0xabcd1234},
4888         {DXGI_FORMAT_R16G16_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4889                 {0x3f000000 /* 0.5f */, 0x3f800000 /* 1.0f */, 0, 0}, 0x3c003800, true},
4890 
4891         {DXGI_FORMAT_R8G8B8A8_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4892                 {0x11, 0x22, 0x33, 0x44}, 0x44332211},
4893         {DXGI_FORMAT_R8G8B8A8_UINT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4894                 {0x100, 0, 0, 0}, 0, false, true},
4895 
4896         {DXGI_FORMAT_R11G11B10_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4897                 {0, 0, 0, 0}, 0},
4898         {DXGI_FORMAT_R11G11B10_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4899                 {0x7ff, 0x7ff, 0x3ff, 0}, 0xffffffff},
4900         {DXGI_FORMAT_R11G11B10_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4901                 {0x7ff, 0, 0x3ff, 0}, 0xffc007ff},
4902         {DXGI_FORMAT_R11G11B10_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4903                 {0x3f000000 /* 0.5f */, 0x3f800000 /* 1.0f */, 0x40000000 /* 2.0f */, 0}, 0x801e0380, true},
4904         {DXGI_FORMAT_R11G11B10_FLOAT, { 0, BUFFER_SIZE / sizeof(uint32_t), 0, 0, D3D12_BUFFER_UAV_FLAG_NONE},
4905                 {0x3f000000 /* 1.0f */, 0 /* 0.0f */, 0xbf800000 /* -1.0f */, 0x3f000000 /* 1.0f */},
4906                 0x00000380, true},
4907     };
4908 
4909     memset(&desc, 0, sizeof(desc));
4910     desc.no_render_target = true;
4911     if (!init_test_context(&context, &desc))
4912         return;
4913     device = context.device;
4914     command_list = context.list;
4915     queue = context.queue;
4916 
4917     cpu_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
4918     gpu_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
4919 
4920     heap_desc.SizeInBytes = 2 * BUFFER_SIZE;
4921     memset(&heap_desc.Properties, 0, sizeof(heap_desc.Properties));
4922     heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT;
4923     heap_desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
4924     heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
4925     hr = ID3D12Device_CreateHeap(device, &heap_desc, &IID_ID3D12Heap, (void **)&heap);
4926     ok(hr == S_OK, "Failed to create heap, hr %#x.\n", hr);
4927 
4928     for (i = 0; i < ARRAY_SIZE(tests); ++i)
4929     {
4930         vkd3d_test_set_context("Test %u", i);
4931 
4932         buffer = create_placed_buffer(device, heap, BUFFER_SIZE, BUFFER_SIZE,
4933                 D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
4934 
4935         for (j = 0; j < ARRAY_SIZE(clear_value); ++j)
4936             clear_value[j] = tests[i].expected ? 0 : ~0u;
4937 
4938         memset(&uav_desc, 0, sizeof(uav_desc));
4939         uav_desc.Format = DXGI_FORMAT_R32_UINT;
4940         uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
4941         uav_desc.Buffer.NumElements = BUFFER_SIZE / sizeof(uint32_t);
4942         ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc,
4943                 get_cpu_descriptor_handle(&context, cpu_heap, 1));
4944         ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc,
4945                 get_cpu_descriptor_handle(&context, gpu_heap, 1));
4946 
4947         uav_desc.Format = tests[i].format;
4948         uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
4949         uav_desc.Buffer = tests[i].buffer_uav;
4950         ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc,
4951                 get_cpu_descriptor_handle(&context, cpu_heap, 0));
4952         ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc,
4953                 get_cpu_descriptor_handle(&context, gpu_heap, 0));
4954 
4955         ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(command_list,
4956                 get_gpu_descriptor_handle(&context, gpu_heap, 1),
4957                 get_cpu_descriptor_handle(&context, cpu_heap, 1),
4958                 buffer, clear_value, 0, NULL);
4959 
4960         uav_barrier(command_list, buffer);
4961 
4962         if (tests[i].is_float)
4963             ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(command_list,
4964                     get_gpu_descriptor_handle(&context, gpu_heap, 0),
4965                     get_cpu_descriptor_handle(&context, cpu_heap, 0),
4966                     buffer, (const float *)tests[i].values, 0, NULL);
4967         else
4968             ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(command_list,
4969                     get_gpu_descriptor_handle(&context, gpu_heap, 0),
4970                     get_cpu_descriptor_handle(&context, cpu_heap, 0),
4971                     buffer, tests[i].values, 0, NULL);
4972 
4973         set_box(&box, 0, 0, 0, 1, 1, 1);
4974         transition_resource_state(command_list, buffer,
4975                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
4976         get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_TYPELESS, &rb, queue, command_list);
4977         box.left = 0;
4978         box.right = uav_desc.Buffer.FirstElement;
4979         check_readback_data_uint(&rb, &box, clear_value[0], 0);
4980         box.left = uav_desc.Buffer.FirstElement;
4981         box.right = uav_desc.Buffer.FirstElement + uav_desc.Buffer.NumElements;
4982         todo_if(tests[i].is_todo)
4983         check_readback_data_uint(&rb, &box, tests[i].expected, tests[i].is_float ? 1 : 0);
4984         box.left = uav_desc.Buffer.FirstElement + uav_desc.Buffer.NumElements;
4985         box.right = BUFFER_SIZE / format_size(uav_desc.Format);
4986         check_readback_data_uint(&rb, &box, clear_value[0], 0);
4987         release_resource_readback(&rb);
4988 
4989         reset_command_list(command_list, context.allocator);
4990         ID3D12Resource_Release(buffer);
4991     }
4992     vkd3d_test_set_context(NULL);
4993 
4994     ID3D12DescriptorHeap_Release(cpu_heap);
4995     ID3D12DescriptorHeap_Release(gpu_heap);
4996     ID3D12Heap_Release(heap);
4997     destroy_test_context(&context);
4998 #undef BUFFER_SIZE
4999 }
5000 
test_clear_unordered_access_view_image(void)5001 static void test_clear_unordered_access_view_image(void)
5002 {
5003     unsigned int expected_colour, actual_colour;
5004     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
5005     ID3D12DescriptorHeap *cpu_heap, *gpu_heap;
5006     ID3D12GraphicsCommandList *command_list;
5007     unsigned int i, j, d, p, x, y, z, layer;
5008     D3D12_HEAP_PROPERTIES heap_properties;
5009     unsigned int image_size, image_depth;
5010     D3D12_RESOURCE_DESC resource_desc;
5011     struct test_context_desc desc;
5012     struct test_context context;
5013     struct resource_readback rb;
5014     ID3D12CommandQueue *queue;
5015     bool is_inside, success;
5016     ID3D12Resource *texture;
5017     ID3D12Device *device;
5018     UINT clear_value[4];
5019     HRESULT hr;
5020 
5021 #define IMAGE_SIZE 16
5022     static const struct
5023     {
5024         DXGI_FORMAT format;
5025         unsigned int image_mips;
5026         unsigned int image_layers;
5027         unsigned int mip_level;
5028         unsigned int first_layer;
5029         unsigned int layer_count;
5030         unsigned int rect_count;
5031         RECT clear_rects[2];
5032         unsigned int values[4];
5033         unsigned int expected;
5034         bool is_float;
5035         bool is_todo;
5036     }
5037     tests[] =
5038     {
5039         /* Test clearing a specific mip level. */
5040         {DXGI_FORMAT_R32_FLOAT,       2, 1, 0, 0, 1, 0, {}, {1,          0, 0, 0}, 1},
5041         {DXGI_FORMAT_R32_FLOAT,       2, 1, 1, 0, 1, 0, {}, {1,          0, 0, 0}, 1},
5042         {DXGI_FORMAT_R32_FLOAT,       2, 1, 0, 0, 1, 0, {}, {0x3f000000, 0, 0, 0}, 0x3f000000, true},
5043         {DXGI_FORMAT_R32_FLOAT,       2, 1, 1, 0, 1, 0, {}, {0x3f000000, 0, 0, 0}, 0x3f000000, true},
5044         /* Test clearing specific array layers. */
5045         {DXGI_FORMAT_R32_FLOAT,       1, IMAGE_SIZE, 0, 0, IMAGE_SIZE, 0, {}, {1, 0, 0, 0}, 1},
5046         {DXGI_FORMAT_R32_FLOAT,       1, IMAGE_SIZE, 0, 3, 2,          0, {}, {1, 0, 0, 0}, 1},
5047         {DXGI_FORMAT_R32_FLOAT,       1, IMAGE_SIZE, 0, 0, IMAGE_SIZE, 0, {},
5048                 {0x3f000000, 0, 0, 0}, 0x3f000000, true},
5049         {DXGI_FORMAT_R32_FLOAT,       1, IMAGE_SIZE, 0, 3, 2,          0, {},
5050                 {0x3f000000, 0, 0, 0}, 0x3f000000, true},
5051         /* Test a single clear rect. */
5052         {DXGI_FORMAT_R32_FLOAT,       1, 1, 0, 0, 1, 1, {{1, 2, IMAGE_SIZE - 4, IMAGE_SIZE - 2}},
5053                 {1,          0, 0, 0}, 1},
5054         {DXGI_FORMAT_R32_FLOAT,       1, 1, 0, 0, 1, 1, {{1, 2, IMAGE_SIZE - 4, IMAGE_SIZE - 2}},
5055                 {0x3f000000, 0, 0, 0}, 0x3f000000, true},
5056         /* Test multiple clear rects. */
5057         {DXGI_FORMAT_R32_FLOAT,       1, 1, 0, 0, 1, 2, {{1, 2, 3, 4}, {5, 6, 7, 8}},
5058                 {1,          0, 0, 0}, 1},
5059         {DXGI_FORMAT_R32_FLOAT,       1, 1, 0, 0, 1, 2, {{1, 2, 3, 4}, {5, 6, 7, 8}},
5060                 {0x3f000000, 0, 0, 0}, 0x3f000000, true},
5061         /* Test uint clears with formats. */
5062         {DXGI_FORMAT_R16G16_UINT,     1, 1, 0, 0, 1, 0, {}, {1,       2, 3, 4}, 0x00020001},
5063         {DXGI_FORMAT_R16G16_UINT,     1, 1, 0, 0, 1, 0, {}, {0x12345, 0, 0, 0}, 0x00002345, false, true},
5064         {DXGI_FORMAT_R16G16_UNORM,    1, 1, 0, 0, 1, 0, {}, {1,       2, 3, 4}, 0x00020001},
5065         {DXGI_FORMAT_R16G16_FLOAT,    1, 1, 0, 0, 1, 0, {}, {1,       2, 3, 4}, 0x00020001},
5066         {DXGI_FORMAT_R8G8B8A8_UINT,   1, 1, 0, 0, 1, 0, {}, {1,       2, 3, 4}, 0x04030201},
5067         {DXGI_FORMAT_R8G8B8A8_UINT,   1, 1, 0, 0, 1, 0, {}, {0x123,   0, 0, 0}, 0x00000023, false, true},
5068         {DXGI_FORMAT_R8G8B8A8_UNORM,  1, 1, 0, 0, 1, 0, {}, {1,       2, 3, 4}, 0x04030201},
5069         {DXGI_FORMAT_R11G11B10_FLOAT, 1, 1, 0, 0, 1, 0, {}, {1,       2, 3, 4}, 0x00c01001},
5070         /* Test float clears with formats. */
5071         {DXGI_FORMAT_R16G16_UNORM,    1, 1, 0, 0, 1, 0, {},
5072                 {0x3f000000 /* 0.5f */, 0x3f800000 /* 1.0f */, 0, 0}, 0xffff8000, true},
5073         {DXGI_FORMAT_R16G16_FLOAT,    1, 1, 0, 0, 1, 0, {},
5074                 {0x3f000000 /* 0.5f */, 0x3f800000 /* 1.0f */, 0, 0}, 0x3c003800, true},
5075         {DXGI_FORMAT_R8G8B8A8_UNORM,  1, 1, 0, 0, 1, 0, {},
5076                 {0x3f000000 /* 0.5f */, 0x3f800000 /* 1.0f */, 0, 0}, 0x0000ff80, true},
5077         {DXGI_FORMAT_R8G8B8A8_UNORM,  1, 1, 0, 0, 1, 0, {},
5078                 {0, 0, 0x3f000000 /* 0.5f */, 0x3f800000 /* 1.0f */}, 0xff800000, true},
5079         {DXGI_FORMAT_R11G11B10_FLOAT, 1, 1, 0, 0, 1, 0, {},
5080                 {0x3f000000 /* 1.0f */, 0 /* 0.0f */, 0xbf800000 /* -1.0f */, 0x3f000000 /* 1.0f */},
5081                 0x00000380, true},
5082     };
5083 
5084     static const struct
5085     {
5086         D3D12_RESOURCE_DIMENSION resource_dim;
5087         D3D12_UAV_DIMENSION view_dim;
5088         bool is_layered;
5089     }
5090     uav_dimensions[] =
5091     {
5092         {D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_UAV_DIMENSION_TEXTURE2D,      false},
5093         {D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_UAV_DIMENSION_TEXTURE2DARRAY, true },
5094         /* Expected behaviour with partial layer coverage is unclear. */
5095         {D3D12_RESOURCE_DIMENSION_TEXTURE3D, D3D12_UAV_DIMENSION_TEXTURE3D,      false},
5096     };
5097 
5098     memset(&desc, 0, sizeof(desc));
5099     desc.no_render_target = true;
5100     if (!init_test_context(&context, &desc))
5101         return;
5102     device = context.device;
5103     command_list = context.list;
5104     queue = context.queue;
5105 
5106     cpu_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
5107     gpu_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
5108 
5109     memset(&heap_properties, 0, sizeof(heap_properties));
5110     heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
5111 
5112     for (d = 0; d < ARRAY_SIZE(uav_dimensions); ++d)
5113     {
5114         for (i = 0; i < ARRAY_SIZE(tests); ++i)
5115         {
5116             vkd3d_test_set_context("Dim %u, Test %u", d, i);
5117 
5118             if (tests[i].image_layers > 1 && !uav_dimensions[d].is_layered)
5119                 continue;
5120 
5121             resource_desc.Dimension = uav_dimensions[d].resource_dim;
5122             resource_desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
5123             resource_desc.Width = IMAGE_SIZE;
5124             resource_desc.Height = IMAGE_SIZE;
5125             if (uav_dimensions[d].resource_dim == D3D12_RESOURCE_DIMENSION_TEXTURE1D)
5126                 resource_desc.Height = 1;
5127             resource_desc.DepthOrArraySize = tests[i].image_layers;
5128             resource_desc.MipLevels = tests[i].image_mips;
5129             resource_desc.Format = tests[i].format;
5130             resource_desc.SampleDesc.Count = 1;
5131             resource_desc.SampleDesc.Quality = 0;
5132             resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
5133             resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
5134 
5135             if (FAILED(hr = ID3D12Device_CreateCommittedResource(device, &heap_properties,
5136                     D3D12_HEAP_FLAG_NONE, &resource_desc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
5137                     NULL, &IID_ID3D12Resource, (void **)&texture)))
5138             {
5139                 skip("Failed to create texture, hr %#x.\n", hr);
5140                 continue;
5141             }
5142 
5143             uav_desc.Format = tests[i].format;
5144             uav_desc.ViewDimension = uav_dimensions[d].view_dim;
5145 
5146             for (j = 0; j < 2; ++j)
5147             {
5148                 unsigned int first_layer = j ? 0 : tests[i].first_layer;
5149                 unsigned int layer_count = j ? tests[i].image_layers : tests[i].layer_count;
5150 
5151                 switch (uav_desc.ViewDimension)
5152                 {
5153                     case D3D12_UAV_DIMENSION_TEXTURE1D:
5154                         uav_desc.Texture1D.MipSlice = tests[i].mip_level;
5155                         break;
5156 
5157                     case D3D12_UAV_DIMENSION_TEXTURE1DARRAY:
5158                         uav_desc.Texture1DArray.MipSlice = tests[i].mip_level;
5159                         uav_desc.Texture1DArray.FirstArraySlice = first_layer;
5160                         uav_desc.Texture1DArray.ArraySize = layer_count;
5161                         break;
5162 
5163                     case D3D12_UAV_DIMENSION_TEXTURE2D:
5164                         uav_desc.Texture2D.MipSlice = tests[i].mip_level;
5165                         uav_desc.Texture2D.PlaneSlice = 0;
5166                         break;
5167 
5168                     case D3D12_UAV_DIMENSION_TEXTURE2DARRAY:
5169                         uav_desc.Texture2DArray.MipSlice = tests[i].mip_level;
5170                         uav_desc.Texture2DArray.FirstArraySlice = first_layer;
5171                         uav_desc.Texture2DArray.ArraySize = layer_count;
5172                         uav_desc.Texture2DArray.PlaneSlice = 0;
5173                         break;
5174 
5175                     case D3D12_UAV_DIMENSION_TEXTURE3D:
5176                         uav_desc.Texture3D.MipSlice = tests[i].mip_level;
5177                         uav_desc.Texture3D.FirstWSlice = first_layer;
5178                         uav_desc.Texture3D.WSize = layer_count;
5179                         break;
5180 
5181                     default:
5182                         continue;
5183                 }
5184 
5185                 ID3D12Device_CreateUnorderedAccessView(device, texture, NULL,
5186                         &uav_desc, get_cpu_descriptor_handle(&context, cpu_heap, j));
5187                 ID3D12Device_CreateUnorderedAccessView(device, texture, NULL,
5188                         &uav_desc, get_cpu_descriptor_handle(&context, gpu_heap, j));
5189             }
5190 
5191             for (j = 0; j < 4; ++j)
5192             {
5193                 clear_value[j] = tests[i].expected ? 0u : ~0u;
5194             }
5195 
5196             ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(command_list,
5197                     get_gpu_descriptor_handle(&context, gpu_heap, 1),
5198                     get_cpu_descriptor_handle(&context, cpu_heap, 1),
5199                     texture, clear_value, 0, NULL);
5200 
5201             uav_barrier(command_list, texture);
5202 
5203             if (tests[i].is_float)
5204                 ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(command_list,
5205                         get_gpu_descriptor_handle(&context, gpu_heap, 0),
5206                         get_cpu_descriptor_handle(&context, cpu_heap, 0),
5207                         texture, (const float *)tests[i].values, tests[i].rect_count, tests[i].clear_rects);
5208             else
5209                 ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(command_list,
5210                         get_gpu_descriptor_handle(&context, gpu_heap, 0),
5211                         get_cpu_descriptor_handle(&context, cpu_heap, 0),
5212                         texture, tests[i].values, tests[i].rect_count, tests[i].clear_rects);
5213 
5214             transition_resource_state(command_list, texture,
5215                     D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
5216 
5217             image_depth = uav_dimensions[d].resource_dim == D3D12_RESOURCE_DIMENSION_TEXTURE3D
5218                     ? max(tests[i].image_layers >> tests[i].mip_level, 1u) : 1;
5219             image_size = max(IMAGE_SIZE >> tests[i].mip_level, 1u);
5220 
5221             for (layer = 0; layer < tests[i].image_layers / image_depth; ++layer)
5222             {
5223                 get_texture_readback_with_command_list(texture,
5224                         tests[i].mip_level + (layer * tests[i].image_mips),
5225                         &rb, queue, command_list);
5226 
5227                 for (p = 0; p < image_depth * image_size * image_size; ++p)
5228                 {
5229                     x = p % image_size;
5230                     y = (p / image_size) % image_size;
5231                     z = p / (image_size * image_size);
5232 
5233                     is_inside = tests[i].rect_count == 0;
5234 
5235                     for (j = 0; j < tests[i].rect_count; ++j)
5236                     {
5237                         if (y >= tests[i].clear_rects[j].top && y < tests[i].clear_rects[j].bottom
5238                                 && x >= tests[i].clear_rects[j].left && x < tests[i].clear_rects[j].right)
5239                         {
5240                             is_inside = true;
5241                             break;
5242                         }
5243                     }
5244 
5245                     if (uav_dimensions[d].resource_dim == D3D12_RESOURCE_DIMENSION_TEXTURE3D)
5246                         is_inside = is_inside && z >= tests[i].first_layer
5247                                 && z < tests[i].first_layer + tests[i].layer_count;
5248                     else
5249                         is_inside = is_inside && layer >= tests[i].first_layer
5250                                 && layer < tests[i].first_layer + tests[i].layer_count;
5251 
5252                     expected_colour = is_inside ? tests[i].expected : clear_value[0];
5253                     actual_colour = get_readback_uint(&rb, x, y, z);
5254                     success = compare_color(actual_colour, expected_colour, tests[i].is_float ? 1 : 0);
5255 
5256                     todo_if(tests[i].is_todo && expected_colour)
5257                     ok(success, "At layer %u, (%u,%u,%u), expected %#x, got %#x.\n",
5258                             layer, x, y, z, expected_colour, actual_colour);
5259 
5260                     if (!success)
5261                         break;
5262                 }
5263 
5264                 release_resource_readback(&rb);
5265                 reset_command_list(command_list, context.allocator);
5266             }
5267 
5268             ID3D12Resource_Release(texture);
5269         }
5270     }
5271 
5272     ID3D12DescriptorHeap_Release(cpu_heap);
5273     ID3D12DescriptorHeap_Release(gpu_heap);
5274     destroy_test_context(&context);
5275 #undef IMAGE_SIZE
5276 }
5277 
test_set_render_targets(void)5278 static void test_set_render_targets(void)
5279 {
5280     ID3D12DescriptorHeap *dsv_heap, *rtv_heap;
5281     ID3D12GraphicsCommandList *command_list;
5282     D3D12_CPU_DESCRIPTOR_HANDLE dsv, rtv;
5283     struct test_context context;
5284     ID3D12Device *device;
5285     HRESULT hr;
5286 
5287     if (!init_test_context(&context, NULL))
5288         return;
5289     device = context.device;
5290     command_list = context.list;
5291 
5292     rtv_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 4);
5293     dsv_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 4);
5294 
5295     dsv = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(dsv_heap);
5296     rtv = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rtv_heap);
5297 
5298     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &rtv, false, NULL);
5299     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &rtv, true, NULL);
5300     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &rtv, true, &dsv);
5301     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, &rtv, true, &dsv);
5302     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, &rtv, false, &dsv);
5303     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, NULL, true, &dsv);
5304     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, NULL, false, &dsv);
5305 
5306     hr = ID3D12GraphicsCommandList_Close(command_list);
5307     ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr);
5308 
5309     ID3D12DescriptorHeap_Release(rtv_heap);
5310     ID3D12DescriptorHeap_Release(dsv_heap);
5311     destroy_test_context(&context);
5312 }
5313 
test_draw_instanced(void)5314 static void test_draw_instanced(void)
5315 {
5316     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
5317     ID3D12GraphicsCommandList *command_list;
5318     struct test_context context;
5319     ID3D12CommandQueue *queue;
5320 
5321     if (!init_test_context(&context, NULL))
5322         return;
5323     command_list = context.list;
5324     queue = context.queue;
5325 
5326     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
5327 
5328     if (!use_warp_device)
5329     {
5330         /* This draw call is ignored. */
5331         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5332     }
5333 
5334     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
5335     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
5336     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
5337     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5338     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5339     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
5340     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5341 
5342     transition_resource_state(command_list, context.render_target,
5343             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5344 
5345     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
5346 
5347     destroy_test_context(&context);
5348 }
5349 
test_draw_indexed_instanced(void)5350 static void test_draw_indexed_instanced(void)
5351 {
5352     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
5353     static const uint16_t indices[] = {0, 1, 2};
5354     ID3D12GraphicsCommandList *command_list;
5355     struct test_context context;
5356     D3D12_INDEX_BUFFER_VIEW ibv;
5357     ID3D12CommandQueue *queue;
5358     ID3D12Resource *ib;
5359 
5360     if (!init_test_context(&context, NULL))
5361         return;
5362     command_list = context.list;
5363     queue = context.queue;
5364 
5365     ib = create_upload_buffer(context.device, sizeof(indices), indices);
5366 
5367     ibv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(ib);
5368     ibv.SizeInBytes = sizeof(indices);
5369     ibv.Format = DXGI_FORMAT_R16_UINT;
5370 
5371     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
5372 
5373     if (!use_warp_device)
5374     {
5375         /* This draw call is ignored. */
5376         ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, 3, 1, 0, 0, 0);
5377     }
5378 
5379     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
5380     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
5381     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
5382     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5383     ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, NULL);
5384     ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, &ibv);
5385     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5386     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
5387     ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, 3, 1, 0, 0, 0);
5388 
5389     transition_resource_state(command_list, context.render_target,
5390             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5391 
5392     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
5393 
5394     ID3D12Resource_Release(ib);
5395     destroy_test_context(&context);
5396 }
5397 
test_draw_no_descriptor_bindings(void)5398 static void test_draw_no_descriptor_bindings(void)
5399 {
5400     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
5401     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
5402     D3D12_DESCRIPTOR_RANGE descriptor_range[2];
5403     ID3D12GraphicsCommandList *command_list;
5404     D3D12_ROOT_PARAMETER root_parameters[2];
5405     struct test_context_desc desc;
5406     struct test_context context;
5407     ID3D12CommandQueue *queue;
5408     HRESULT hr;
5409 
5410     memset(&desc, 0, sizeof(desc));
5411     desc.no_root_signature = true;
5412     if (!init_test_context(&context, &desc))
5413         return;
5414     command_list = context.list;
5415     queue = context.queue;
5416 
5417     descriptor_range[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
5418     descriptor_range[0].NumDescriptors = 2;
5419     descriptor_range[0].BaseShaderRegister = 0;
5420     descriptor_range[0].RegisterSpace = 0;
5421     descriptor_range[0].OffsetInDescriptorsFromTableStart = 1;
5422     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
5423     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
5424     root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_range[0];
5425     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
5426 
5427     descriptor_range[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
5428     descriptor_range[1].NumDescriptors = 1;
5429     descriptor_range[1].BaseShaderRegister = 0;
5430     descriptor_range[1].RegisterSpace = 0;
5431     descriptor_range[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
5432     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
5433     root_parameters[1].DescriptorTable.NumDescriptorRanges = 1;
5434     root_parameters[1].DescriptorTable.pDescriptorRanges = &descriptor_range[1];
5435     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
5436 
5437     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
5438     root_signature_desc.pParameters = root_parameters;
5439     root_signature_desc.NumStaticSamplers = 0;
5440     root_signature_desc.pStaticSamplers = NULL;
5441     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
5442     hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
5443     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
5444 
5445     context.pipeline_state = create_pipeline_state(context.device,
5446             context.root_signature, context.render_target_desc.Format, NULL, NULL, NULL);
5447 
5448     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
5449 
5450     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
5451     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
5452     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
5453     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5454     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5455     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
5456     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5457 
5458     transition_resource_state(command_list, context.render_target,
5459             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5460 
5461     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
5462 
5463     destroy_test_context(&context);
5464 }
5465 
test_multiple_render_targets(void)5466 static void test_multiple_render_targets(void)
5467 {
5468     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
5469     struct vec4 expected_vec4 = {0.0f, 0.0f, 0.0f, 1.0f};
5470     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
5471     ID3D12GraphicsCommandList *command_list;
5472     D3D12_CPU_DESCRIPTOR_HANDLE rtvs[3];
5473     ID3D12Resource *render_targets[2];
5474     struct test_context_desc desc;
5475     struct test_context context;
5476     ID3D12CommandQueue *queue;
5477     unsigned int i;
5478     HRESULT hr;
5479 
5480     static const DWORD ps_code[] =
5481     {
5482 #if 0
5483         void main(out float4 target0 : SV_Target0, out float4 target1 : SV_Target1,
5484                 out float4 target2 : SV_Target2)
5485         {
5486             target0 = float4(1.0f, 0.0f, 0.0f, 1.0f);
5487             target1 = float4(2.0f, 0.0f, 0.0f, 1.0f);
5488             target2 = float4(3.0f, 0.0f, 0.0f, 1.0f);
5489         }
5490 #endif
5491         0x43425844, 0xc4325131, 0x8ba4a693, 0x08d15431, 0xcb990885, 0x00000001, 0x0000013c, 0x00000003,
5492         0x0000002c, 0x0000003c, 0x000000a0, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
5493         0x0000005c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
5494         0x0000000f, 0x00000050, 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x00000050,
5495         0x00000002, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074,
5496         0x58454853, 0x00000094, 0x00000050, 0x00000025, 0x0100086a, 0x03000065, 0x001020f2, 0x00000000,
5497         0x03000065, 0x001020f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x08000036, 0x001020f2,
5498         0x00000000, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x08000036, 0x001020f2,
5499         0x00000001, 0x00004002, 0x40000000, 0x00000000, 0x00000000, 0x3f800000, 0x08000036, 0x001020f2,
5500         0x00000002, 0x00004002, 0x40400000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e,
5501     };
5502     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
5503 
5504     memset(&desc, 0, sizeof(desc));
5505     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
5506     desc.rt_descriptor_count = ARRAY_SIZE(rtvs);
5507     desc.no_pipeline = true;
5508     if (!init_test_context(&context, &desc))
5509         return;
5510     command_list = context.list;
5511     queue = context.queue;
5512 
5513     init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, &ps, NULL);
5514     pso_desc.NumRenderTargets = ARRAY_SIZE(rtvs);
5515     for (i = 0; i < ARRAY_SIZE(rtvs); ++i)
5516         pso_desc.RTVFormats[i] = desc.rt_format;
5517     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
5518             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
5519     ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
5520 
5521     rtvs[0] = get_cpu_rtv_handle(&context, context.rtv_heap, 2);
5522     rtvs[1] = get_cpu_rtv_handle(&context, context.rtv_heap, 0);
5523     rtvs[2] = get_cpu_rtv_handle(&context, context.rtv_heap, 1);
5524 
5525     create_render_target(&context, &desc, &render_targets[0], &rtvs[0]);
5526     create_render_target(&context, &desc, &render_targets[1], &rtvs[2]);
5527 
5528     for (i = 0; i < ARRAY_SIZE(rtvs); ++i)
5529         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtvs[i], white, 0, NULL);
5530 
5531     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, ARRAY_SIZE(rtvs), rtvs, false, NULL);
5532     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
5533     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
5534     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5535     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5536     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
5537     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5538 
5539     transition_resource_state(command_list, context.render_target,
5540             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5541     transition_resource_state(command_list, render_targets[0],
5542             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5543     transition_resource_state(command_list, render_targets[1],
5544             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5545 
5546     expected_vec4.x = 2.0f;
5547     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_vec4, 0);
5548     reset_command_list(command_list, context.allocator);
5549     expected_vec4.x = 1.0f;
5550     check_sub_resource_vec4(render_targets[0], 0, queue, command_list, &expected_vec4, 0);
5551     reset_command_list(command_list, context.allocator);
5552     expected_vec4.x = 3.0f;
5553     check_sub_resource_vec4(render_targets[1], 0, queue, command_list, &expected_vec4, 0);
5554     reset_command_list(command_list, context.allocator);
5555 
5556     transition_resource_state(command_list, context.render_target,
5557             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
5558     transition_resource_state(command_list, render_targets[0],
5559             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
5560     transition_resource_state(command_list, render_targets[1],
5561             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
5562 
5563     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, ARRAY_SIZE(rtvs), &context.rtv, true, NULL);
5564     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
5565     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
5566     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5567     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5568     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
5569     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5570 
5571     transition_resource_state(command_list, context.render_target,
5572             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5573     transition_resource_state(command_list, render_targets[0],
5574             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5575     transition_resource_state(command_list, render_targets[1],
5576             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5577 
5578     expected_vec4.x = 1.0f;
5579     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_vec4, 0);
5580     reset_command_list(command_list, context.allocator);
5581     expected_vec4.x = 3.0f;
5582     check_sub_resource_vec4(render_targets[0], 0, queue, command_list, &expected_vec4, 0);
5583     reset_command_list(command_list, context.allocator);
5584     expected_vec4.x = 2.0f;
5585     check_sub_resource_vec4(render_targets[1], 0, queue, command_list, &expected_vec4, 0);
5586     reset_command_list(command_list, context.allocator);
5587 
5588     for (i = 0; i < ARRAY_SIZE(render_targets); ++i)
5589         ID3D12Resource_Release(render_targets[i]);
5590     destroy_test_context(&context);
5591 }
5592 
test_unknown_rtv_format(void)5593 static void test_unknown_rtv_format(void)
5594 {
5595     static const struct vec4 white = {1.0f, 1.0f, 1.0f, 1.0f};
5596     struct vec4 expected_vec4 = {0.0f, 0.0f, 0.0f, 1.0f};
5597     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
5598     ID3D12GraphicsCommandList *command_list;
5599     D3D12_RENDER_TARGET_VIEW_DESC rtv_desc;
5600     D3D12_CPU_DESCRIPTOR_HANDLE rtvs[3];
5601     ID3D12Resource *render_targets[2];
5602     struct depth_stencil_resource ds;
5603     struct test_context_desc desc;
5604     struct test_context context;
5605     ID3D12CommandQueue *queue;
5606     unsigned int i;
5607     HRESULT hr;
5608 
5609     static const DWORD ps_code[] =
5610     {
5611 #if 0
5612         void main(out float4 target1 : SV_Target1, out float4 target2 : SV_Target2)
5613         {
5614             target1 = float4(2.0f, 0.0f, 0.0f, 1.0f);
5615             target2 = float4(3.0f, 0.0f, 0.0f, 1.0f);
5616         }
5617 #endif
5618         0x43425844, 0x980554be, 0xb8743fb0, 0xf5bb8deb, 0x639feaf8, 0x00000001, 0x000000f4, 0x00000003,
5619         0x0000002c, 0x0000003c, 0x00000088, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
5620         0x00000044, 0x00000002, 0x00000008, 0x00000038, 0x00000001, 0x00000000, 0x00000003, 0x00000001,
5621         0x0000000f, 0x00000038, 0x00000002, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x545f5653,
5622         0x65677261, 0xabab0074, 0x52444853, 0x00000064, 0x00000040, 0x00000019, 0x03000065, 0x001020f2,
5623         0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x08000036, 0x001020f2, 0x00000001, 0x00004002,
5624         0x40000000, 0x00000000, 0x00000000, 0x3f800000, 0x08000036, 0x001020f2, 0x00000002, 0x00004002,
5625         0x40400000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e,
5626     };
5627     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
5628 
5629     memset(&desc, 0, sizeof(desc));
5630     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
5631     desc.rt_descriptor_count = 16;
5632     desc.no_pipeline = true;
5633     if (!init_test_context(&context, &desc))
5634         return;
5635     command_list = context.list;
5636     queue = context.queue;
5637 
5638     init_depth_stencil(&ds, context.device, 32, 32, 1, 1, DXGI_FORMAT_D32_FLOAT, 0, NULL);
5639 
5640     init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, &ps, NULL);
5641     pso_desc.NumRenderTargets = ARRAY_SIZE(rtvs);
5642     for (i = 0; i < ARRAY_SIZE(rtvs); ++i)
5643         pso_desc.RTVFormats[i] = desc.rt_format;
5644     pso_desc.RTVFormats[0] = DXGI_FORMAT_UNKNOWN;
5645     pso_desc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
5646     pso_desc.DepthStencilState.DepthEnable = true;
5647     pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
5648     pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
5649     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
5650             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
5651     ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
5652 
5653     rtvs[0] = get_cpu_rtv_handle(&context, context.rtv_heap, 0);
5654     rtvs[1] = get_cpu_rtv_handle(&context, context.rtv_heap, 1);
5655     rtvs[2] = get_cpu_rtv_handle(&context, context.rtv_heap, 2);
5656     create_render_target(&context, &desc, &render_targets[0], &rtvs[1]);
5657     create_render_target(&context, &desc, &render_targets[1], &rtvs[2]);
5658 
5659     for (i = 0; i < ARRAY_SIZE(rtvs); ++i)
5660         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtvs[i], &white.x, 0, NULL);
5661 
5662     /* NULL RTV */
5663     memset(&rtv_desc, 0, sizeof(rtv_desc));
5664     rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
5665     rtv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
5666     rtv_desc.Texture2D.MipSlice = 0;
5667     rtv_desc.Texture2D.PlaneSlice = 0;
5668     ID3D12Device_CreateRenderTargetView(context.device, NULL, &rtv_desc,
5669             get_cpu_rtv_handle(&context, context.rtv_heap, 0));
5670 
5671     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, ARRAY_SIZE(rtvs), rtvs, false, &ds.dsv_handle);
5672     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
5673     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
5674     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5675     set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.5f, 0.5f);
5676     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5677     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
5678     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5679 
5680     transition_resource_state(command_list, context.render_target,
5681             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5682     transition_resource_state(command_list, render_targets[0],
5683             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5684     transition_resource_state(command_list, render_targets[1],
5685             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5686 
5687     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &white, 0);
5688     reset_command_list(command_list, context.allocator);
5689     expected_vec4.x = 2.0f;
5690     check_sub_resource_vec4(render_targets[0], 0, queue, command_list, &expected_vec4, 0);
5691     reset_command_list(command_list, context.allocator);
5692     expected_vec4.x = 3.0f;
5693     check_sub_resource_vec4(render_targets[1], 0, queue, command_list, &expected_vec4, 0);
5694 
5695     reset_command_list(command_list, context.allocator);
5696     transition_resource_state(command_list, ds.texture,
5697             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
5698     check_sub_resource_float(ds.texture, 0, queue, command_list, 0.5f, 1);
5699 
5700     for (i = 0; i < ARRAY_SIZE(render_targets); ++i)
5701         ID3D12Resource_Release(render_targets[i]);
5702     destroy_depth_stencil(&ds);
5703     destroy_test_context(&context);
5704 }
5705 
test_unknown_dsv_format(void)5706 static void test_unknown_dsv_format(void)
5707 {
5708     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
5709     ID3D12GraphicsCommandList *command_list;
5710     struct depth_stencil_resource ds;
5711     D3D12_CLEAR_VALUE clear_value;
5712     struct test_context_desc desc;
5713     struct test_context context;
5714     ID3D12CommandQueue *queue;
5715     HRESULT hr;
5716 
5717     static const DWORD ps_color_code[] =
5718     {
5719 #if 0
5720         float4 color;
5721 
5722         float4 main(float4 position : SV_POSITION) : SV_Target
5723         {
5724             return color;
5725         }
5726 #endif
5727         0x43425844, 0xd18ead43, 0x8b8264c1, 0x9c0a062d, 0xfc843226, 0x00000001, 0x000000e0, 0x00000003,
5728         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
5729         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49,
5730         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
5731         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000044, 0x00000050,
5732         0x00000011, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2,
5733         0x00000000, 0x06000036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e,
5734     };
5735     static const D3D12_SHADER_BYTECODE ps_color = {ps_color_code, sizeof(ps_color_code)};
5736     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
5737     static const struct vec4 green = {0.0f, 1.0f, 0.0f, 1.0f};
5738     static const struct vec4 red = {1.0f, 0.0f, 0.0f, 1.0f};
5739 
5740     memset(&desc, 0, sizeof(desc));
5741     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
5742     desc.no_root_signature = true;
5743     if (!init_test_context(&context, &desc))
5744         return;
5745     command_list = context.list;
5746     queue = context.queue;
5747 
5748     clear_value.Format = DXGI_FORMAT_D32_FLOAT;
5749     clear_value.DepthStencil.Depth = 0.5f;
5750     clear_value.DepthStencil.Stencil = 0;
5751     init_depth_stencil(&ds, context.device, 32, 32, 1, 1, DXGI_FORMAT_D32_FLOAT, 0, &clear_value);
5752 
5753     context.root_signature = create_32bit_constants_root_signature(context.device,
5754             0, 4, D3D12_SHADER_VISIBILITY_PIXEL);
5755 
5756     /* DSVFormat = DXGI_FORMAT_UNKNOWN and D3D12_DEPTH_WRITE_MASK_ZERO */
5757     init_pipeline_state_desc(&pso_desc, context.root_signature, desc.rt_format, NULL, &ps_color, NULL);
5758     pso_desc.DSVFormat = DXGI_FORMAT_UNKNOWN;
5759     pso_desc.DepthStencilState.DepthEnable = true;
5760     pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
5761     pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_EQUAL;
5762     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
5763             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
5764     ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
5765 
5766     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
5767     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
5768             D3D12_CLEAR_FLAG_DEPTH, 0.5f, 0, 0, NULL);
5769 
5770     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, &ds.dsv_handle);
5771     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
5772     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
5773     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5774     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
5775 
5776     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &green.x, 0);
5777     set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.5f, 0.5f);
5778     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5779     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5780 
5781     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &red.x, 0);
5782     set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 1.0f, 1.0f);
5783     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5784     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5785     set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.0f, 0.0f);
5786     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5787     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5788     set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.55f, 0.55f);
5789     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5790     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5791 
5792     transition_resource_state(command_list, ds.texture,
5793             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
5794     check_sub_resource_float(ds.texture, 0, queue, command_list, 0.5f, 1);
5795 
5796     reset_command_list(command_list, context.allocator);
5797     transition_resource_state(command_list, context.render_target,
5798             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5799     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &green, 0);
5800 
5801     /* DSVFormat = DXGI_FORMAT_UNKNOWN and no DSV */
5802     reset_command_list(command_list, context.allocator);
5803     transition_resource_state(command_list, ds.texture,
5804             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE);
5805     transition_resource_state(command_list, context.render_target,
5806             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
5807 
5808     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
5809 
5810     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
5811     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
5812     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
5813     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5814     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
5815 
5816     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &red.x, 0);
5817     set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.0f, 0.0f);
5818     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5819     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5820 
5821     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &green.x, 0);
5822     set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.5f, 0.5f);
5823     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5824     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5825 
5826     transition_resource_state(command_list, context.render_target,
5827             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5828     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &green, 0);
5829 
5830     /* DSVFormat = DXGI_FORMAT_UNKNOWN and D3D12_COMPARISON_FUNC_ALWAYS */
5831     ID3D12PipelineState_Release(context.pipeline_state);
5832     pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
5833     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
5834             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
5835     ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
5836 
5837     reset_command_list(command_list, context.allocator);
5838     transition_resource_state(command_list, context.render_target,
5839             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
5840 
5841     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
5842 
5843     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, &ds.dsv_handle);
5844     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
5845     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
5846     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5847     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
5848 
5849     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &red.x, 0);
5850     set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.0f, 0.0f);
5851     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5852     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5853 
5854     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &green.x, 0);
5855     set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.6f, 0.6f);
5856     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5857     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5858 
5859     transition_resource_state(command_list, context.render_target,
5860             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5861     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &green, 0);
5862 
5863     /* DSVFormat = DXGI_FORMAT_UNKNOWN and depth write */
5864     ID3D12PipelineState_Release(context.pipeline_state);
5865     pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
5866     pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
5867     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
5868             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
5869     ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
5870 
5871     reset_command_list(command_list, context.allocator);
5872     transition_resource_state(command_list, context.render_target,
5873             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
5874 
5875     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
5876             D3D12_CLEAR_FLAG_DEPTH, 0.0f, 0, 0, NULL);
5877 
5878     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
5879     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
5880     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5881     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
5882 
5883     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, &ds.dsv_handle);
5884     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &red.x, 0);
5885     set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 1.0f, 1.0f);
5886     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5887     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5888 
5889     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
5890     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &green.x, 0);
5891     set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.6f, 0.6f);
5892     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
5893     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
5894 
5895     transition_resource_state(command_list, context.render_target,
5896             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
5897     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &green, 0);
5898 
5899     reset_command_list(command_list, context.allocator);
5900     transition_resource_state(command_list, ds.texture,
5901             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
5902     check_sub_resource_float(ds.texture, 0, queue, command_list, 1.0f, 1);
5903 
5904     destroy_depth_stencil(&ds);
5905     destroy_test_context(&context);
5906 }
5907 
test_append_aligned_element(void)5908 static void test_append_aligned_element(void)
5909 {
5910     ID3D12GraphicsCommandList *command_list;
5911     D3D12_INPUT_LAYOUT_DESC input_layout;
5912     D3D12_VERTEX_BUFFER_VIEW vbv[6];
5913     struct test_context_desc desc;
5914     struct test_context context;
5915     struct resource_readback rb;
5916     ID3D12CommandQueue *queue;
5917     ID3D12Resource *vb[3];
5918     unsigned int color;
5919 
5920     /* Semantic names are case-insensitive. */
5921     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
5922     {
5923         {"CoLoR",    2, DXGI_FORMAT_R32G32_FLOAT,       1, D3D12_APPEND_ALIGNED_ELEMENT,
5924                 D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1},
5925         {"ColoR",    3, DXGI_FORMAT_R32G32_FLOAT,       5, D3D12_APPEND_ALIGNED_ELEMENT,
5926                 D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1},
5927         {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT,
5928                 D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
5929         {"ColoR",    0, DXGI_FORMAT_R32G32_FLOAT,       5, D3D12_APPEND_ALIGNED_ELEMENT,
5930                 D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1},
5931         {"cOLOr",    1, DXGI_FORMAT_R32G32_FLOAT,       1, D3D12_APPEND_ALIGNED_ELEMENT,
5932                 D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1},
5933     };
5934     static const DWORD vs_code[] =
5935     {
5936 #if 0
5937         struct vs_in
5938         {
5939             float4 position : POSITION;
5940             float2 color_xy : COLOR0;
5941             float2 color_zw : COLOR1;
5942             unsigned int instance_id : SV_INSTANCEID;
5943         };
5944 
5945         struct vs_out
5946         {
5947             float4 position : SV_POSITION;
5948             float2 color_xy : COLOR0;
5949             float2 color_zw : COLOR1;
5950         };
5951 
5952         struct vs_out main(struct vs_in i)
5953         {
5954             struct vs_out o;
5955 
5956             o.position = i.position;
5957             o.position.x += i.instance_id * 0.5;
5958             o.color_xy = i.color_xy;
5959             o.color_zw = i.color_zw;
5960 
5961             return o;
5962         }
5963 #endif
5964         0x43425844, 0x52e3bf46, 0x6300403d, 0x624cffe4, 0xa4fc0013, 0x00000001, 0x00000214, 0x00000003,
5965         0x0000002c, 0x000000bc, 0x00000128, 0x4e475349, 0x00000088, 0x00000004, 0x00000008, 0x00000068,
5966         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000071, 0x00000000, 0x00000000,
5967         0x00000003, 0x00000001, 0x00000303, 0x00000071, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
5968         0x00000303, 0x00000077, 0x00000000, 0x00000008, 0x00000001, 0x00000003, 0x00000101, 0x49534f50,
5969         0x4e4f4954, 0x4c4f4300, 0x5300524f, 0x4e495f56, 0x4e415453, 0x44494543, 0xababab00, 0x4e47534f,
5970         0x00000064, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, 0x00000003, 0x00000000,
5971         0x0000000f, 0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000c03, 0x0000005c,
5972         0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x0000030c, 0x505f5653, 0x5449534f, 0x004e4f49,
5973         0x4f4c4f43, 0xabab0052, 0x52444853, 0x000000e4, 0x00010040, 0x00000039, 0x0300005f, 0x001010f2,
5974         0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x00101032, 0x00000002, 0x04000060,
5975         0x00101012, 0x00000003, 0x00000008, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065,
5976         0x00102032, 0x00000001, 0x03000065, 0x001020c2, 0x00000001, 0x02000068, 0x00000001, 0x05000056,
5977         0x00100012, 0x00000000, 0x0010100a, 0x00000003, 0x09000032, 0x00102012, 0x00000000, 0x0010000a,
5978         0x00000000, 0x00004001, 0x3f000000, 0x0010100a, 0x00000000, 0x05000036, 0x001020e2, 0x00000000,
5979         0x00101e56, 0x00000000, 0x05000036, 0x00102032, 0x00000001, 0x00101046, 0x00000001, 0x05000036,
5980         0x001020c2, 0x00000001, 0x00101406, 0x00000002, 0x0100003e,
5981     };
5982     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
5983     static const DWORD ps_code[] =
5984     {
5985 #if 0
5986         struct vs_out
5987         {
5988             float4 position : SV_POSITION;
5989             float2 color_xy : COLOR0;
5990             float2 color_zw : COLOR1;
5991         };
5992 
5993         float4 main(struct vs_out i) : SV_TARGET
5994         {
5995             return float4(i.color_xy.xy, i.color_zw.xy);
5996         }
5997 #endif
5998         0x43425844, 0x64e48a09, 0xaa484d46, 0xe40a6e78, 0x9885edf3, 0x00000001, 0x00000118, 0x00000003,
5999         0x0000002c, 0x00000098, 0x000000cc, 0x4e475349, 0x00000064, 0x00000003, 0x00000008, 0x00000050,
6000         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000,
6001         0x00000003, 0x00000001, 0x00000303, 0x0000005c, 0x00000001, 0x00000000, 0x00000003, 0x00000001,
6002         0x00000c0c, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x4e47534f, 0x0000002c,
6003         0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f,
6004         0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000044, 0x00000040, 0x00000011, 0x03001062,
6005         0x00101032, 0x00000001, 0x03001062, 0x001010c2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
6006         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e,
6007     };
6008     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
6009     static const struct
6010     {
6011         struct vec4 position;
6012     }
6013     stream0[] =
6014     {
6015         {{-1.0f, -1.0f, 0.0f, 1.0f}},
6016         {{-1.0f,  1.0f, 0.0f, 1.0f}},
6017         {{-0.5f, -1.0f, 0.0f, 1.0f}},
6018         {{-0.5f,  1.0f, 0.0f, 1.0f}},
6019     };
6020     static const struct
6021     {
6022         struct vec2 color2;
6023         struct vec2 color1;
6024     }
6025     stream1[] =
6026     {
6027         {{0.5f, 0.5f}, {0.0f, 1.0f}},
6028         {{0.5f, 0.5f}, {0.0f, 1.0f}},
6029         {{0.5f, 0.5f}, {1.0f, 1.0f}},
6030         {{0.5f, 0.5f}, {1.0f, 1.0f}},
6031     };
6032     static const struct
6033     {
6034         struct vec2 color3;
6035         struct vec2 color0;
6036     }
6037     stream2[] =
6038     {
6039         {{0.5f, 0.5f}, {1.0f, 0.0f}},
6040         {{0.5f, 0.5f}, {0.0f, 1.0f}},
6041         {{0.5f, 0.5f}, {0.0f, 0.0f}},
6042         {{0.5f, 0.5f}, {1.0f, 0.0f}},
6043     };
6044     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
6045 
6046     memset(&desc, 0, sizeof(desc));
6047     desc.rt_width = 640;
6048     desc.no_root_signature = true;
6049     if (!init_test_context(&context, &desc))
6050         return;
6051     command_list = context.list;
6052     queue = context.queue;
6053 
6054     context.root_signature = create_empty_root_signature(context.device,
6055             D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
6056     input_layout.pInputElementDescs = layout_desc;
6057     input_layout.NumElements = ARRAY_SIZE(layout_desc);
6058     context.pipeline_state = create_pipeline_state(context.device,
6059             context.root_signature, context.render_target_desc.Format, &vs, &ps, &input_layout);
6060 
6061     memset(vbv, 0, sizeof(vbv));
6062     vb[0] = create_upload_buffer(context.device, sizeof(stream0), stream0);
6063     vbv[0].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb[0]);
6064     vbv[0].StrideInBytes = sizeof(*stream0);
6065     vbv[0].SizeInBytes = sizeof(stream0);
6066 
6067     vb[1] = create_upload_buffer(context.device, sizeof(stream1), stream1);
6068     vbv[1].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb[1]);
6069     vbv[1].StrideInBytes = sizeof(*stream1);
6070     vbv[1].SizeInBytes = sizeof(stream1);
6071 
6072     vb[2] = create_upload_buffer(context.device, sizeof(stream2), stream2);
6073     vbv[5].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb[2]);
6074     vbv[5].StrideInBytes = sizeof(*stream2);
6075     vbv[5].SizeInBytes = sizeof(stream2);
6076 
6077     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
6078 
6079     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
6080     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
6081     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
6082     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
6083     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
6084     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
6085     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
6086     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 4, 0, 0);
6087 
6088     transition_resource_state(command_list, context.render_target,
6089             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
6090     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
6091     color = get_readback_uint(&rb, 80, 16, 0);
6092     ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
6093     color = get_readback_uint(&rb, 240, 16, 0);
6094     ok(compare_color(color, 0xff00ff00, 1), "Got unexpected color 0x%08x.\n", color);
6095     color = get_readback_uint(&rb, 400, 16, 0);
6096     ok(compare_color(color, 0xffff0000, 1), "Got unexpected color 0x%08x.\n", color);
6097     color = get_readback_uint(&rb, 560, 16, 0);
6098     ok(compare_color(color, 0xffff00ff, 1), "Got unexpected color 0x%08x.\n", color);
6099     release_resource_readback(&rb);
6100 
6101     ID3D12Resource_Release(vb[2]);
6102     ID3D12Resource_Release(vb[1]);
6103     ID3D12Resource_Release(vb[0]);
6104     destroy_test_context(&context);
6105 }
6106 
test_gpu_virtual_address(void)6107 static void test_gpu_virtual_address(void)
6108 {
6109     D3D12_GPU_VIRTUAL_ADDRESS vb_offset, ib_offset;
6110     ID3D12GraphicsCommandList *command_list;
6111     D3D12_INPUT_LAYOUT_DESC input_layout;
6112     struct test_context_desc desc;
6113     D3D12_VERTEX_BUFFER_VIEW vbv;
6114     struct test_context context;
6115     D3D12_INDEX_BUFFER_VIEW ibv;
6116     ID3D12CommandQueue *queue;
6117     ID3D12Resource *buffer;
6118     HRESULT hr;
6119     BYTE *ptr;
6120 
6121     static const DWORD vs_code[] =
6122     {
6123 #if 0
6124         void main(float4 in_position : POSITION, float4 in_color : COLOR,
6125                 out float4 out_position : SV_POSITION, out float4 out_color : COLOR)
6126         {
6127             out_position = in_position;
6128             out_color = in_color;
6129         }
6130 #endif
6131         0x43425844, 0xa58fc911, 0x280038e9, 0x14cfff54, 0xe43fc328, 0x00000001, 0x00000144, 0x00000003,
6132         0x0000002c, 0x0000007c, 0x000000d0, 0x4e475349, 0x00000048, 0x00000002, 0x00000008, 0x00000038,
6133         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, 0x00000000, 0x00000000,
6134         0x00000003, 0x00000001, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0x4c4f4300, 0xab00524f, 0x4e47534f,
6135         0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000,
6136         0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x505f5653,
6137         0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x58454853, 0x0000006c, 0x00010050, 0x0000001b,
6138         0x0100086a, 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x001010f2, 0x00000001, 0x04000067,
6139         0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x001020f2,
6140         0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x001020f2, 0x00000001, 0x00101e46, 0x00000001,
6141         0x0100003e,
6142     };
6143     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
6144     static const DWORD ps_code[] =
6145     {
6146 #if 0
6147         void main(float4 in_position : SV_POSITION, float4 in_color : COLOR,
6148                 out float4 out_color : SV_TARGET)
6149         {
6150             out_color = in_color;
6151         }
6152 #endif
6153         0x43425844, 0x1a6def50, 0x9c069300, 0x7cce68f0, 0x621239b9, 0x00000001, 0x000000f8, 0x00000003,
6154         0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
6155         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000,
6156         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
6157         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
6158         0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x58454853, 0x0000003c, 0x00000050,
6159         0x0000000f, 0x0100086a, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
6160         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e,
6161     };
6162     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
6163     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
6164     static const uint32_t indices[] = {0, 1, 2, 3};
6165     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
6166     {
6167         {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT,       0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
6168         {"COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
6169     };
6170     static const struct
6171     {
6172         struct vec2 position;
6173         struct vec4 color;
6174     }
6175     quad[] =
6176     {
6177         {{-1.0f, -1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}},
6178         {{-1.0f,  1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}},
6179         {{ 1.0f, -1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}},
6180         {{ 1.0f,  1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}},
6181     };
6182 
6183     memset(&desc, 0, sizeof(desc));
6184     desc.no_root_signature = true;
6185     if (!init_test_context(&context, &desc))
6186         return;
6187     command_list = context.list;
6188     queue = context.queue;
6189 
6190     context.root_signature = create_empty_root_signature(context.device,
6191             D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
6192     input_layout.pInputElementDescs = layout_desc;
6193     input_layout.NumElements = ARRAY_SIZE(layout_desc);
6194     context.pipeline_state = create_pipeline_state(context.device,
6195             context.root_signature, context.render_target_desc.Format, &vs, &ps, &input_layout);
6196 
6197     vb_offset = 0x200;
6198     ib_offset = 0x500;
6199     buffer = create_upload_buffer(context.device, ib_offset + sizeof(indices), NULL);
6200 
6201     hr = ID3D12Resource_Map(buffer, 0, NULL, (void **)&ptr);
6202     ok(SUCCEEDED(hr), "Failed to map upload buffer, hr %#x.\n", hr);
6203     memcpy(ptr + vb_offset, quad, sizeof(quad));
6204     memcpy(ptr + ib_offset, indices, sizeof(indices));
6205     ID3D12Resource_Unmap(buffer, 0, NULL);
6206 
6207     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(buffer) + vb_offset;
6208     vbv.StrideInBytes = sizeof(*quad);
6209     vbv.SizeInBytes = sizeof(quad);
6210     ibv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(buffer) + ib_offset;
6211     ibv.SizeInBytes = sizeof(indices);
6212     ibv.Format = DXGI_FORMAT_R32_UINT;
6213 
6214     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
6215 
6216     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
6217     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
6218     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
6219     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
6220     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
6221     ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, &ibv);
6222     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
6223     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
6224     ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, 4, 1, 0, 0, 0);
6225 
6226     transition_resource_state(command_list, context.render_target,
6227             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
6228     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
6229 
6230     ID3D12Resource_Release(buffer);
6231     destroy_test_context(&context);
6232 }
6233 
test_fragment_coords(void)6234 static void test_fragment_coords(void)
6235 {
6236     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
6237     ID3D12GraphicsCommandList *command_list;
6238     D3D12_INPUT_LAYOUT_DESC input_layout;
6239     struct test_context_desc desc;
6240     D3D12_VERTEX_BUFFER_VIEW vbv;
6241     struct test_context context;
6242     struct resource_readback rb;
6243     const struct vec4 *v = NULL;
6244     struct vec4 expected = {0};
6245     ID3D12CommandQueue *queue;
6246     unsigned int i, x = 0, y;
6247     ID3D12Resource *vb;
6248     bool all_match;
6249 
6250     static const DWORD vs_code[] =
6251     {
6252 #if 0
6253         void main(float4 in_position : POSITION, out float4 out_position : SV_POSITION)
6254         {
6255             out_position = in_position;
6256         }
6257 #endif
6258         0x43425844, 0xa7a2f22d, 0x83ff2560, 0xe61638bd, 0x87e3ce90, 0x00000001, 0x000000d8, 0x00000003,
6259         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
6260         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
6261         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
6262         0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040,
6263         0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
6264         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
6265     };
6266     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
6267     static const DWORD ps_code[] =
6268     {
6269 #if 0
6270         float4 main(float4 position: sv_position) : sv_target
6271         {
6272             return position;
6273         }
6274 #endif
6275         0x43425844, 0xac408178, 0x2ca4213f, 0x4f2551e1, 0x1626b422, 0x00000001, 0x000000d8, 0x00000003,
6276         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
6277         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x705f7673, 0x7469736f, 0x006e6f69,
6278         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
6279         0x00000000, 0x0000000f, 0x745f7673, 0x65677261, 0xabab0074, 0x52444853, 0x0000003c, 0x00000040,
6280         0x0000000f, 0x04002064, 0x001010f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
6281         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
6282     };
6283     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
6284     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
6285     {
6286         {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
6287     };
6288     static const struct vec4 vertices[] =
6289     {
6290         {-1.0f, -1.0f, 0.00f, 1.00f},
6291         {-1.0f,  1.0f, 0.00f, 1.00f},
6292         { 1.0f, -1.0f, 0.00f, 1.00f},
6293         { 1.0f,  1.0f, 0.00f, 1.00f},
6294 
6295         {-1.0f, -1.0f, 0.25f, 1.00f},
6296         {-1.0f,  1.0f, 0.25f, 1.00f},
6297         { 1.0f, -1.0f, 0.25f, 1.00f},
6298         { 1.0f,  1.0f, 0.25f, 1.00f},
6299 
6300         {-1.0f, -1.0f, 0.50f, 1.00f},
6301         {-1.0f,  1.0f, 0.50f, 1.00f},
6302         { 1.0f, -1.0f, 0.50f, 1.00f},
6303         { 1.0f,  1.0f, 0.50f, 1.00f},
6304 
6305         {-1.0f, -1.0f, 0.75f, 1.00f},
6306         {-1.0f,  1.0f, 0.75f, 1.00f},
6307         { 1.0f, -1.0f, 0.75f, 1.00f},
6308         { 1.0f,  1.0f, 0.75f, 1.00f},
6309 
6310         {-1.0f, -1.0f, 1.00f, 1.00f},
6311         {-1.0f,  1.0f, 1.00f, 1.00f},
6312         { 1.0f, -1.0f, 1.00f, 1.00f},
6313         { 1.0f,  1.0f, 1.00f, 1.00f},
6314 
6315         {-1.0f, -1.0f, 1.00f, 0.50f},
6316         {-1.0f,  1.0f, 1.00f, 0.50f},
6317         { 1.0f, -1.0f, 1.00f, 0.50f},
6318         { 1.0f,  1.0f, 1.00f, 0.50f},
6319 
6320         {-1.0f, -1.0f, 1.00f, 0.25f},
6321         {-1.0f,  1.0f, 1.00f, 0.25f},
6322         { 1.0f, -1.0f, 1.00f, 0.25f},
6323         { 1.0f,  1.0f, 1.00f, 0.25f},
6324     };
6325 
6326     memset(&desc, 0, sizeof(desc));
6327     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
6328     desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
6329     desc.no_pipeline = true;
6330     if (!init_test_context(&context, &desc))
6331         return;
6332     command_list = context.list;
6333     queue = context.queue;
6334 
6335     input_layout.pInputElementDescs = layout_desc;
6336     input_layout.NumElements = ARRAY_SIZE(layout_desc);
6337     context.pipeline_state = create_pipeline_state(context.device,
6338             context.root_signature, context.render_target_desc.Format, &vs, &ps, &input_layout);
6339 
6340     vb = create_upload_buffer(context.device, sizeof(vertices), vertices);
6341     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
6342     vbv.StrideInBytes = sizeof(*vertices);
6343     vbv.SizeInBytes = sizeof(vertices);
6344 
6345     for (i = 0; i < ARRAY_SIZE(vertices) / 4; ++i)
6346     {
6347         vkd3d_test_set_context("Test %u", i);
6348 
6349         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
6350 
6351         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
6352         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
6353         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
6354         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
6355         set_viewport(&context.viewport, 0.0f, 0.0f, 32.0f, 32.0f, 0.0f, 1.0f);
6356         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
6357         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
6358         ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
6359         ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 4 * i, 0);
6360 
6361         set_viewport(&context.viewport, 10.0f, 10.0f, 20.0f, 30.0f, 0.0f, 1.0f);
6362         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
6363         ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 4 * i, 0);
6364 
6365         transition_resource_state(command_list, context.render_target,
6366                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
6367 
6368         get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
6369         all_match = true;
6370         for (y = 0; y < rb.height; ++y)
6371         {
6372             for (x = 0; x < rb.width; ++x)
6373             {
6374                 v = get_readback_vec4(&rb, x, y);
6375                 expected.x = x + 0.5f;
6376                 expected.y = y + 0.5f;
6377                 expected.z = vertices[4 * i].z / vertices[4 * i].w;
6378                 expected.w = vertices[4 * i].w;
6379                 if (!compare_vec4(v, &expected, 2))
6380                 {
6381                     all_match = false;
6382                     break;
6383                 }
6384             }
6385             if (!all_match)
6386                 break;
6387         }
6388         ok(all_match, "Got {%.8e, %.8e, %.8e, %.8e} expected {%.8e, %.8e, %.8e, %.8e} at (%u, %u).\n",
6389                 v->x, v->y, v->z, v->w, expected.x, expected.y, expected.z, expected.w, x, y);
6390         release_resource_readback(&rb);
6391 
6392         reset_command_list(command_list, context.allocator);
6393         transition_resource_state(command_list, context.render_target,
6394                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
6395     }
6396     vkd3d_test_set_context(NULL);
6397 
6398     ID3D12Resource_Release(vb);
6399     destroy_test_context(&context);
6400 }
6401 
test_fractional_viewports(void)6402 static void test_fractional_viewports(void)
6403 {
6404     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
6405     ID3D12GraphicsCommandList *command_list;
6406     D3D12_INPUT_LAYOUT_DESC input_layout;
6407     struct test_context_desc desc;
6408     D3D12_VERTEX_BUFFER_VIEW vbv;
6409     struct test_context context;
6410     struct resource_readback rb;
6411     ID3D12CommandQueue *queue;
6412     D3D12_VIEWPORT viewport;
6413     unsigned int i, x, y;
6414     ID3D12Resource *vb;
6415 
6416     static const DWORD vs_code[] =
6417     {
6418 #if 0
6419         void main(in float4 in_position : POSITION,
6420                 in float2 in_texcoord : TEXCOORD,
6421                 out float4 position : SV_Position,
6422                 out float2 texcoord : TEXCOORD)
6423         {
6424             position = in_position;
6425             texcoord = in_texcoord;
6426         }
6427 #endif
6428         0x43425844, 0x4df282ca, 0x85c8bbfc, 0xd44ad19f, 0x1158be97, 0x00000001, 0x00000148, 0x00000003,
6429         0x0000002c, 0x00000080, 0x000000d8, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
6430         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, 0x00000000, 0x00000000,
6431         0x00000003, 0x00000001, 0x00000303, 0x49534f50, 0x4e4f4954, 0x58455400, 0x524f4f43, 0xabab0044,
6432         0x4e47534f, 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003,
6433         0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000c03,
6434         0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x52444853, 0x00000068,
6435         0x00010040, 0x0000001a, 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x00101032, 0x00000001,
6436         0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102032, 0x00000001, 0x05000036,
6437         0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x00102032, 0x00000001, 0x00101046,
6438         0x00000001, 0x0100003e,
6439     };
6440     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
6441     static const DWORD ps_code[] =
6442     {
6443 #if 0
6444         float4 main(float4 position : SV_Position,
6445                 float2 texcoord : TEXCOORD) : SV_Target
6446         {
6447             return float4(position.xy, texcoord);
6448         }
6449 #endif
6450         0x43425844, 0xa15616bc, 0x6862ab1c, 0x28b915c0, 0xdb0df67c, 0x00000001, 0x0000011c, 0x00000003,
6451         0x0000002c, 0x00000084, 0x000000b8, 0x4e475349, 0x00000050, 0x00000002, 0x00000008, 0x00000038,
6452         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x00000044, 0x00000000, 0x00000000,
6453         0x00000003, 0x00000001, 0x00000303, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f,
6454         0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
6455         0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x0000005c,
6456         0x00000040, 0x00000017, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03001062, 0x00101032,
6457         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, 0x00102032, 0x00000000, 0x00101046,
6458         0x00000000, 0x05000036, 0x001020c2, 0x00000000, 0x00101406, 0x00000001, 0x0100003e,
6459     };
6460     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
6461     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
6462     {
6463         {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
6464         {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
6465     };
6466     static const struct
6467     {
6468         struct vec2 position;
6469         struct vec2 texcoord;
6470     }
6471     quad[] =
6472     {
6473         {{-1.0f, -1.0f}, {0.0f, 0.0f}},
6474         {{-1.0f,  1.0f}, {0.0f, 1.0f}},
6475         {{ 1.0f, -1.0f}, {1.0f, 0.0f}},
6476         {{ 1.0f,  1.0f}, {1.0f, 1.0f}},
6477     };
6478     static const float viewport_offsets[] =
6479     {
6480         0.0f, 1.0f / 2.0f, 1.0f / 4.0f, 1.0f / 8.0f, 1.0f / 16.0f, 1.0f / 32.0f,
6481         1.0f / 64.0f, 1.0f / 128.0f, 1.0f / 256.0f, 63.0f / 128.0f,
6482     };
6483 
6484     memset(&desc, 0, sizeof(desc));
6485     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
6486     desc.no_root_signature = true;
6487     if (!init_test_context(&context, &desc))
6488         return;
6489     command_list = context.list;
6490     queue = context.queue;
6491 
6492     context.root_signature = create_empty_root_signature(context.device,
6493             D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
6494 
6495     input_layout.pInputElementDescs = layout_desc;
6496     input_layout.NumElements = ARRAY_SIZE(layout_desc);
6497     context.pipeline_state = create_pipeline_state(context.device,
6498             context.root_signature, desc.rt_format, &vs, &ps, &input_layout);
6499 
6500     vb = create_upload_buffer(context.device, sizeof(quad), quad);
6501 
6502     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
6503     vbv.StrideInBytes = sizeof(*quad);
6504     vbv.SizeInBytes = sizeof(quad);
6505 
6506     for (i = 0; i < ARRAY_SIZE(viewport_offsets); ++i)
6507     {
6508         set_viewport(&viewport, viewport_offsets[i], viewport_offsets[i],
6509                 context.render_target_desc.Width, context.render_target_desc.Height, 0.0f, 1.0f);
6510 
6511         if (i)
6512             transition_resource_state(command_list, context.render_target,
6513                     D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
6514 
6515         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
6516 
6517         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
6518         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
6519         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
6520         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
6521         ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
6522         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &viewport);
6523         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
6524         ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
6525 
6526         transition_resource_state(command_list, context.render_target,
6527                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
6528 
6529         get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
6530         for (y = 0; y < rb.height; ++y)
6531         {
6532             for (x = 0; x < rb.width; ++x)
6533             {
6534                 const struct vec4 *v = get_readback_vec4(&rb, x, y);
6535                 struct vec4 expected = {x + 0.5f, y + 0.5f,
6536                         (x + 0.5f - viewport_offsets[i]) / context.render_target_desc.Width,
6537                         1.0f - (y + 0.5f - viewport_offsets[i]) / context.render_target_desc.Height};
6538                 ok(compare_float(v->x, expected.x, 0) && compare_float(v->y, expected.y, 0),
6539                         "Got fragcoord {%.8e, %.8e}, expected {%.8e, %.8e} at (%u, %u), offset %.8e.\n",
6540                         v->x, v->y, expected.x, expected.y, x, y, viewport_offsets[i]);
6541                 ok(compare_float(v->z, expected.z, 2) && compare_float(v->w, expected.w, 2),
6542                         "Got texcoord {%.8e, %.8e}, expected {%.8e, %.8e} at (%u, %u), offset %.8e.\n",
6543                         v->z, v->w, expected.z, expected.w, x, y, viewport_offsets[i]);
6544             }
6545         }
6546         release_resource_readback(&rb);
6547 
6548         reset_command_list(command_list, context.allocator);
6549     }
6550 
6551     ID3D12Resource_Release(vb);
6552     destroy_test_context(&context);
6553 }
6554 
test_scissor(void)6555 static void test_scissor(void)
6556 {
6557     ID3D12GraphicsCommandList *command_list;
6558     struct test_context_desc desc;
6559     struct test_context context;
6560     struct resource_readback rb;
6561     ID3D12CommandQueue *queue;
6562     unsigned int color;
6563     RECT scissor_rect;
6564 
6565     static const DWORD ps_code[] =
6566     {
6567 #if 0
6568         float4 main(float4 position : SV_POSITION) : SV_Target
6569         {
6570             return float4(0.0, 1.0, 0.0, 1.0);
6571         }
6572 #endif
6573         0x43425844, 0x30240e72, 0x012f250c, 0x8673c6ea, 0x392e4cec, 0x00000001, 0x000000d4, 0x00000003,
6574         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
6575         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49,
6576         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
6577         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000038, 0x00000040,
6578         0x0000000e, 0x03000065, 0x001020f2, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002,
6579         0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x0100003e,
6580     };
6581     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
6582     static const float red[] = {1.0f, 0.0f, 0.0f, 1.0f};
6583 
6584     memset(&desc, 0, sizeof(desc));
6585     desc.rt_width = 640;
6586     desc.rt_height = 480;
6587     desc.ps = &ps;
6588     if (!init_test_context(&context, &desc))
6589         return;
6590     command_list = context.list;
6591     queue = context.queue;
6592 
6593     set_rect(&scissor_rect, 160, 120, 480, 360);
6594 
6595     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, red, 0, NULL);
6596 
6597     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
6598     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
6599     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
6600     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
6601     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
6602     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &scissor_rect);
6603     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
6604 
6605     transition_resource_state(command_list, context.render_target,
6606             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
6607 
6608     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
6609     color = get_readback_uint(&rb, 320, 60, 0);
6610     ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
6611     color = get_readback_uint(&rb, 80, 240, 0);
6612     ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
6613     color = get_readback_uint(&rb, 320, 240, 0);
6614     ok(compare_color(color, 0xff00ff00, 1), "Got unexpected color 0x%08x.\n", color);
6615     color = get_readback_uint(&rb, 560, 240, 0);
6616     ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
6617     color = get_readback_uint(&rb, 320, 420, 0);
6618     ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
6619     release_resource_readback(&rb);
6620 
6621     destroy_test_context(&context);
6622 }
6623 
test_draw_depth_no_ps(void)6624 static void test_draw_depth_no_ps(void)
6625 {
6626     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
6627     ID3D12GraphicsCommandList *command_list;
6628     D3D12_INPUT_LAYOUT_DESC input_layout;
6629     struct depth_stencil_resource ds;
6630     struct test_context_desc desc;
6631     D3D12_VERTEX_BUFFER_VIEW vbv;
6632     struct test_context context;
6633     ID3D12CommandQueue *queue;
6634     ID3D12Resource *vb;
6635     HRESULT hr;
6636 
6637     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
6638     {
6639         {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
6640     };
6641     static const struct
6642     {
6643         struct vec4 position;
6644     }
6645     quad[] =
6646     {
6647         {{-1.0f, -1.0f, 0.5f, 1.0f}},
6648         {{-1.0f,  1.0f, 0.5f, 1.0f}},
6649         {{ 1.0f, -1.0f, 0.5f, 1.0f}},
6650         {{ 1.0f,  1.0f, 0.5f, 1.0f}},
6651     };
6652     static const DWORD vs_code[] =
6653     {
6654 #if 0
6655         void main(float4 in_position : POSITION, out float4 out_position : SV_POSITION)
6656         {
6657             out_position = in_position;
6658         }
6659 #endif
6660         0x43425844, 0xa7a2f22d, 0x83ff2560, 0xe61638bd, 0x87e3ce90, 0x00000001, 0x000000d8, 0x00000003,
6661         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
6662         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
6663         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
6664         0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040,
6665         0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
6666         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
6667     };
6668     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
6669 
6670     memset(&desc, 0, sizeof(desc));
6671     desc.no_render_target = true;
6672     if (!init_test_context(&context, &desc))
6673         return;
6674     command_list = context.list;
6675     queue = context.queue;
6676 
6677     vb = create_upload_buffer(context.device, sizeof(quad), quad);
6678 
6679     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
6680     vbv.StrideInBytes = sizeof(*quad);
6681     vbv.SizeInBytes = sizeof(quad);
6682 
6683     init_depth_stencil(&ds, context.device, 640, 480, 1, 1, DXGI_FORMAT_D32_FLOAT, 0, NULL);
6684     set_viewport(&context.viewport, 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 1.0f);
6685     set_rect(&context.scissor_rect, 0, 0, 640, 480);
6686 
6687     context.root_signature = create_empty_root_signature(context.device,
6688             D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
6689     input_layout.pInputElementDescs = layout_desc;
6690     input_layout.NumElements = ARRAY_SIZE(layout_desc);
6691     init_pipeline_state_desc(&pso_desc, context.root_signature, 0,  &vs, NULL, &input_layout);
6692     memset(&pso_desc.PS, 0, sizeof(pso_desc.PS));
6693     pso_desc.NumRenderTargets = 0;
6694     pso_desc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
6695     pso_desc.DepthStencilState.DepthEnable = true;
6696     pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
6697     pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
6698     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
6699             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
6700     ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
6701 
6702     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
6703             D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, NULL);
6704 
6705     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, NULL, false, &ds.dsv_handle);
6706     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
6707     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
6708     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
6709     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
6710     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
6711     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
6712     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
6713 
6714     transition_resource_state(command_list, ds.texture,
6715             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
6716     check_sub_resource_float(ds.texture, 0, queue, command_list, 0.5f, 1);
6717 
6718     destroy_depth_stencil(&ds);
6719     ID3D12Resource_Release(vb);
6720     destroy_test_context(&context);
6721 }
6722 
test_draw_depth_only(void)6723 static void test_draw_depth_only(void)
6724 {
6725     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
6726     ID3D12GraphicsCommandList *command_list;
6727     struct depth_stencil_resource ds;
6728     struct test_context_desc desc;
6729     struct resource_readback rb;
6730     struct test_context context;
6731     ID3D12CommandQueue *queue;
6732     unsigned int i, j;
6733     HRESULT hr;
6734 
6735     static const DWORD ps_code[] =
6736     {
6737 #if 0
6738         float depth;
6739 
6740         float main() : SV_Depth
6741         {
6742             return depth;
6743         }
6744 #endif
6745         0x43425844, 0x91af6cd0, 0x7e884502, 0xcede4f54, 0x6f2c9326, 0x00000001, 0x000000b0, 0x00000003,
6746         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
6747         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0xffffffff,
6748         0x00000e01, 0x445f5653, 0x68747065, 0xababab00, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
6749         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x02000065, 0x0000c001, 0x05000036, 0x0000c001,
6750         0x0020800a, 0x00000000, 0x00000000, 0x0100003e,
6751     };
6752     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
6753     static const struct
6754     {
6755         float clear_depth;
6756         float depth;
6757         float expected_depth;
6758     }
6759     tests[] =
6760     {
6761         {0.0f, 0.0f, 0.0f},
6762         {0.0f, 0.7f, 0.0f},
6763         {0.0f, 0.8f, 0.0f},
6764         {0.0f, 0.5f, 0.0f},
6765 
6766         {1.0f, 0.0f, 0.0f},
6767         {1.0f, 0.7f, 0.7f},
6768         {1.0f, 0.8f, 0.8f},
6769         {1.0f, 0.5f, 0.5f},
6770     };
6771 
6772     memset(&desc, 0, sizeof(desc));
6773     desc.no_render_target = true;
6774     if (!init_test_context(&context, &desc))
6775         return;
6776     command_list = context.list;
6777     queue = context.queue;
6778 
6779     init_depth_stencil(&ds, context.device, 640, 480, 1, 1, DXGI_FORMAT_D32_FLOAT, 0, NULL);
6780     set_viewport(&context.viewport, 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 1.0f);
6781     set_rect(&context.scissor_rect, 0, 0, 640, 480);
6782 
6783     context.root_signature = create_32bit_constants_root_signature(context.device,
6784             0, 1, D3D12_SHADER_VISIBILITY_PIXEL);
6785     init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, &ps, NULL);
6786     pso_desc.NumRenderTargets = 0;
6787     pso_desc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
6788     pso_desc.DepthStencilState.DepthEnable = true;
6789     pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
6790     pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
6791     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
6792             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
6793     ok(SUCCEEDED(hr), "Failed to create graphics pipeline state, hr %#x.\n", hr);
6794 
6795     for (i = 0; i < ARRAY_SIZE(tests); ++i)
6796     {
6797         vkd3d_test_set_context("Test %u", i);
6798 
6799         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
6800                 D3D12_CLEAR_FLAG_DEPTH, tests[i].clear_depth, 0, 0, NULL);
6801 
6802         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, NULL, false, &ds.dsv_handle);
6803         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
6804         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
6805         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
6806         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
6807         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
6808 
6809         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 1, &tests[i].depth, 0);
6810         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
6811 
6812         transition_resource_state(command_list, ds.texture,
6813                 D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
6814         check_sub_resource_float(ds.texture, 0, queue, command_list, tests[i].expected_depth, 1);
6815 
6816         reset_command_list(command_list, context.allocator);
6817         transition_resource_state(command_list, ds.texture,
6818                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE);
6819     }
6820     vkd3d_test_set_context(NULL);
6821 
6822     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
6823             D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, NULL);
6824     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, NULL, false, &ds.dsv_handle);
6825     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
6826     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
6827     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
6828     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
6829     for (i = 0; i < 4; ++i)
6830     {
6831         for (j = 0; j < 4; ++j)
6832         {
6833             float depth = 1.0f / 16.0f * (j + 4 * i);
6834             ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 1, &depth, 0);
6835 
6836             set_viewport(&context.viewport, 160.0f * j, 120.0f * i, 160.0f, 120.0f, 0.0f, 1.0f);
6837             ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
6838 
6839             ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
6840         }
6841     }
6842     transition_resource_state(command_list, ds.texture,
6843             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
6844     get_texture_readback_with_command_list(ds.texture, 0, &rb, queue, command_list);
6845     for (i = 0; i < 4; ++i)
6846     {
6847         for (j = 0; j < 4; ++j)
6848         {
6849             float obtained_depth, expected_depth;
6850 
6851             obtained_depth = get_readback_float(&rb, 80 + j * 160, 60 + i * 120);
6852             expected_depth = 1.0f / 16.0f * (j + 4 * i);
6853             ok(compare_float(obtained_depth, expected_depth, 1),
6854                     "Got unexpected depth %.8e at (%u, %u), expected %.8e.\n",
6855                     obtained_depth, j, i, expected_depth);
6856         }
6857     }
6858     release_resource_readback(&rb);
6859 
6860     destroy_depth_stencil(&ds);
6861     destroy_test_context(&context);
6862 }
6863 
test_draw_uav_only(void)6864 static void test_draw_uav_only(void)
6865 {
6866     ID3D12DescriptorHeap *cpu_descriptor_heap, *descriptor_heap;
6867     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
6868     D3D12_DESCRIPTOR_RANGE descriptor_range;
6869     ID3D12GraphicsCommandList *command_list;
6870     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
6871     D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
6872     D3D12_ROOT_PARAMETER root_parameter;
6873     struct test_context_desc desc;
6874     struct test_context context;
6875     ID3D12CommandQueue *queue;
6876     ID3D12Resource *resource;
6877     unsigned int i;
6878     HRESULT hr;
6879 
6880     static const DWORD ps_code[] =
6881     {
6882 #if 0
6883         RWTexture2D<int> u;
6884 
6885         void main()
6886         {
6887             InterlockedAdd(u[uint2(0, 0)], 1);
6888         }
6889 #endif
6890         0x43425844, 0x237a8398, 0xe7b34c17, 0xa28c91a4, 0xb3614d73, 0x00000001, 0x0000009c, 0x00000003,
6891         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
6892         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000048, 0x00000050, 0x00000012, 0x0100086a,
6893         0x0400189c, 0x0011e000, 0x00000000, 0x00003333, 0x0a0000ad, 0x0011e000, 0x00000000, 0x00004002,
6894         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004001, 0x00000001, 0x0100003e,
6895     };
6896     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
6897     static const float zero[4] = {0};
6898 
6899     memset(&desc, 0, sizeof(desc));
6900     desc.no_render_target = true;
6901     if (!init_test_context(&context, &desc))
6902         return;
6903     command_list = context.list;
6904     queue = context.queue;
6905 
6906     descriptor_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
6907     descriptor_range.NumDescriptors = 1;
6908     descriptor_range.BaseShaderRegister = 0;
6909     descriptor_range.RegisterSpace = 0;
6910     descriptor_range.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
6911     root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
6912     root_parameter.DescriptorTable.NumDescriptorRanges = 1;
6913     root_parameter.DescriptorTable.pDescriptorRanges = &descriptor_range;
6914     root_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
6915     root_signature_desc.NumParameters = 1;
6916     root_signature_desc.pParameters = &root_parameter;
6917     root_signature_desc.NumStaticSamplers = 0;
6918     root_signature_desc.pStaticSamplers = NULL;
6919     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
6920     hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
6921     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
6922 
6923     context.pipeline_state = create_pipeline_state(context.device, context.root_signature, 0, NULL, &ps, NULL);
6924 
6925     resource = create_default_texture(context.device, 1, 1, DXGI_FORMAT_R32_SINT,
6926             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
6927 
6928     descriptor_heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
6929     cpu_descriptor_heap = create_cpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
6930     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(descriptor_heap);
6931     gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap);
6932     ID3D12Device_CreateUnorderedAccessView(context.device, resource, NULL, NULL, cpu_handle);
6933     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cpu_descriptor_heap);
6934     ID3D12Device_CreateUnorderedAccessView(context.device, resource, NULL, NULL, cpu_handle);
6935 
6936     ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(command_list,
6937             gpu_handle, cpu_handle, resource, zero, 0, NULL);
6938 
6939     set_rect(&context.scissor_rect, 0, 0, 1000, 1000);
6940     set_viewport(&context.viewport, 0.0f, 0.0f, 1.0f, 100.0f, 0.0f, 0.0f);
6941 
6942     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
6943     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
6944     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
6945     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
6946     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
6947     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
6948     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
6949 
6950     for (i = 0; i < 5; ++i)
6951         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
6952 
6953     transition_resource_state(command_list, resource,
6954             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
6955     bug_if(is_radv_device(context.device))
6956     check_sub_resource_uint(resource, 0, queue, command_list, 500, 0);
6957 
6958     ID3D12DescriptorHeap_Release(cpu_descriptor_heap);
6959     ID3D12DescriptorHeap_Release(descriptor_heap);
6960     ID3D12Resource_Release(resource);
6961     destroy_test_context(&context);
6962 }
6963 
test_texture_resource_barriers(void)6964 static void test_texture_resource_barriers(void)
6965 {
6966     ID3D12CommandAllocator *command_allocator;
6967     ID3D12GraphicsCommandList *command_list;
6968     D3D12_RESOURCE_BARRIER barriers[8];
6969     ID3D12CommandQueue *queue;
6970     ID3D12Resource *resource;
6971     ID3D12Device *device;
6972     ULONG refcount;
6973     HRESULT hr;
6974 
6975     if (!(device = create_device()))
6976     {
6977         skip("Failed to create device.\n");
6978         return;
6979     }
6980 
6981     queue = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
6982 
6983     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
6984             &IID_ID3D12CommandAllocator, (void **)&command_allocator);
6985     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
6986 
6987     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
6988             command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list);
6989     ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
6990 
6991     resource = create_default_texture(device, 32, 32, DXGI_FORMAT_R8G8B8A8_UNORM,
6992             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COMMON);
6993 
6994     barriers[0].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
6995     barriers[0].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
6996     barriers[0].Transition.pResource = resource;
6997     barriers[0].Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
6998     barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON;
6999     barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
7000     ID3D12GraphicsCommandList_ResourceBarrier(command_list, 1, &barriers[0]);
7001 
7002     barriers[1].Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
7003     barriers[1].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
7004     barriers[1].UAV.pResource = resource;
7005     ID3D12GraphicsCommandList_ResourceBarrier(command_list, 1, &barriers[1]);
7006 
7007     barriers[2].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
7008     barriers[2].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
7009     barriers[2].Transition.pResource = resource;
7010     barriers[2].Transition.Subresource = 0;
7011     barriers[2].Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
7012     barriers[2].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
7013     ID3D12GraphicsCommandList_ResourceBarrier(command_list, 1, &barriers[2]);
7014 
7015     barriers[3].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
7016     barriers[3].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
7017     barriers[3].Transition.pResource = resource;
7018     barriers[3].Transition.Subresource = 0;
7019     barriers[3].Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE;
7020     barriers[3].Transition.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE
7021             | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
7022     ID3D12GraphicsCommandList_ResourceBarrier(command_list, 1, &barriers[3]);
7023 
7024     barriers[4].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
7025     barriers[4].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
7026     barriers[4].Transition.pResource = resource;
7027     barriers[4].Transition.Subresource = 0;
7028     barriers[4].Transition.StateBefore = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE
7029             | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
7030     barriers[4].Transition.StateAfter  = D3D12_RESOURCE_STATE_COPY_SOURCE;
7031     ID3D12GraphicsCommandList_ResourceBarrier(command_list, 1, &barriers[4]);
7032 
7033     barriers[5].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
7034     barriers[5].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
7035     barriers[5].Transition.pResource = resource;
7036     barriers[5].Transition.Subresource = 0;
7037     barriers[5].Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE;
7038     barriers[5].Transition.StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
7039     ID3D12GraphicsCommandList_ResourceBarrier(command_list, 1, &barriers[5]);
7040 
7041     barriers[6].Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
7042     barriers[6].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
7043     barriers[6].UAV.pResource = resource;
7044     ID3D12GraphicsCommandList_ResourceBarrier(command_list, 1, &barriers[6]);
7045     ID3D12GraphicsCommandList_ResourceBarrier(command_list, 1, &barriers[6]);
7046 
7047     barriers[7].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
7048     barriers[7].Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
7049     barriers[7].Transition.pResource = resource;
7050     barriers[7].Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
7051     barriers[7].Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
7052     barriers[7].Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON;
7053     ID3D12GraphicsCommandList_ResourceBarrier(command_list, 1, &barriers[7]);
7054 
7055     ID3D12GraphicsCommandList_ResourceBarrier(command_list, 8, barriers);
7056 
7057     hr = ID3D12GraphicsCommandList_Close(command_list);
7058     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
7059     exec_command_list(queue, command_list);
7060     wait_queue_idle(device, queue);
7061 
7062     ID3D12GraphicsCommandList_Release(command_list);
7063     ID3D12CommandAllocator_Release(command_allocator);
7064     ID3D12Resource_Release(resource);
7065     ID3D12CommandQueue_Release(queue);
7066     refcount = ID3D12Device_Release(device);
7067     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
7068 }
7069 
test_device_removed_reason(void)7070 static void test_device_removed_reason(void)
7071 {
7072     D3D12_COMMAND_QUEUE_DESC command_queue_desc;
7073     ID3D12CommandAllocator *command_allocator;
7074     ID3D12GraphicsCommandList *command_list;
7075     ID3D12CommandQueue *queue, *tmp_queue;
7076     ID3D12Device *device;
7077     ULONG refcount;
7078     HRESULT hr;
7079 
7080     if (!(device = create_device()))
7081     {
7082         skip("Failed to create device.\n");
7083         return;
7084     }
7085 
7086     hr = ID3D12Device_GetDeviceRemovedReason(device);
7087     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
7088 
7089     command_queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
7090     command_queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
7091     command_queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
7092     command_queue_desc.NodeMask = 0;
7093     hr = ID3D12Device_CreateCommandQueue(device, &command_queue_desc,
7094             &IID_ID3D12CommandQueue, (void **)&queue);
7095     ok(SUCCEEDED(hr), "Failed to create command queue, hr %#x.\n", hr);
7096 
7097     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
7098             &IID_ID3D12CommandAllocator, (void **)&command_allocator);
7099     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
7100 
7101     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
7102             command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list);
7103     ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
7104 
7105     /* Execute a command list in the recording state. */
7106     exec_command_list(queue, command_list);
7107 
7108     hr = ID3D12Device_GetDeviceRemovedReason(device);
7109     ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
7110 
7111     hr = ID3D12Device_CreateCommandQueue(device, &command_queue_desc,
7112             &IID_ID3D12CommandQueue, (void **)&tmp_queue);
7113     todo ok(hr == DXGI_ERROR_DEVICE_REMOVED, "Got unexpected hr %#x.\n", hr);
7114     if (SUCCEEDED(hr))
7115         ID3D12CommandQueue_Release(tmp_queue);
7116 
7117     hr = ID3D12Device_GetDeviceRemovedReason(device);
7118     ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
7119 
7120     ID3D12GraphicsCommandList_Release(command_list);
7121     ID3D12CommandAllocator_Release(command_allocator);
7122     ID3D12CommandQueue_Release(queue);
7123     refcount = ID3D12Device_Release(device);
7124     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
7125 }
7126 
test_map_resource(void)7127 static void test_map_resource(void)
7128 {
7129     D3D12_HEAP_PROPERTIES heap_properties;
7130     D3D12_RESOURCE_DESC resource_desc;
7131     ID3D12Resource *resource;
7132     ID3D12Device *device;
7133     ULONG refcount;
7134     void *data;
7135     HRESULT hr;
7136 
7137     if (!(device = create_device()))
7138     {
7139         skip("Failed to create device.\n");
7140         return;
7141     }
7142 
7143     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
7144     resource_desc.Alignment = 0;
7145     resource_desc.Width = 32;
7146     resource_desc.Height = 32;
7147     resource_desc.DepthOrArraySize = 1;
7148     resource_desc.MipLevels = 1;
7149     resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
7150     resource_desc.SampleDesc.Count = 1;
7151     resource_desc.SampleDesc.Quality = 0;
7152     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
7153     resource_desc.Flags = 0;
7154 
7155     memset(&heap_properties, 0, sizeof(heap_properties));
7156     heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
7157     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
7158             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
7159             &IID_ID3D12Resource, (void **)&resource);
7160     ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
7161 
7162     /* Resources on a DEFAULT heap cannot be mapped. */
7163     data = (void *)0xdeadbeef;
7164     hr = ID3D12Resource_Map(resource, 0, NULL, &data);
7165     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
7166     ok(data == (void *)0xdeadbeef, "Pointer was modified %p.\n", data);
7167 
7168     ID3D12Resource_Release(resource);
7169 
7170     heap_properties.Type = D3D12_HEAP_TYPE_CUSTOM;
7171     heap_properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE;
7172     heap_properties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0;
7173     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
7174             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
7175             &IID_ID3D12Resource, (void **)&resource);
7176     if (FAILED(hr))
7177     {
7178         skip("Failed to create texture on custom heap.\n");
7179     }
7180     else
7181     {
7182         /* The data pointer must be NULL for the UNKNOWN layout. */
7183         data = (void *)0xdeadbeef;
7184         hr = ID3D12Resource_Map(resource, 0, NULL, &data);
7185         ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
7186         ok(data == (void *)0xdeadbeef, "Pointer was modified %p.\n", data);
7187 
7188         /* Texture on custom heaps can be mapped, but the address doesn't get disclosed to applications */
7189         hr = ID3D12Resource_Map(resource, 0, NULL, NULL);
7190         todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
7191         ID3D12Resource_Unmap(resource, 0, NULL);
7192 
7193         ID3D12Resource_Release(resource);
7194     }
7195 
7196     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
7197     resource_desc.Height = 1;
7198     resource_desc.Format = DXGI_FORMAT_UNKNOWN;
7199     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
7200 
7201     memset(&heap_properties, 0, sizeof(heap_properties));
7202     heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
7203     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
7204             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL,
7205             &IID_ID3D12Resource, (void **)&resource);
7206     ok(hr == S_OK, "Failed to create committed resource, hr %#x.\n", hr);
7207 
7208     /* Resources on a DEFAULT heap cannot be mapped. */
7209     data = (void *)0xdeadbeef;
7210     hr = ID3D12Resource_Map(resource, 0, NULL, &data);
7211     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
7212     ok(data == (void *)0xdeadbeef, "Pointer was modified %p.\n", data);
7213 
7214     ID3D12Resource_Release(resource);
7215 
7216     heap_properties.Type = D3D12_HEAP_TYPE_UPLOAD;
7217     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
7218             &resource_desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL,
7219             &IID_ID3D12Resource, (void **)&resource);
7220     ok(hr == S_OK, "Failed to create committed resource, hr %#x.\n", hr);
7221 
7222     data = NULL;
7223     hr = ID3D12Resource_Map(resource, 0, NULL, &data);
7224     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
7225     ok(data, "Got NULL pointer.\n");
7226     ID3D12Resource_Unmap(resource, 0, NULL);
7227 
7228     data = (void *)0xdeadbeef;
7229     hr = ID3D12Resource_Map(resource, 1, NULL, &data);
7230     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
7231     ok(data == (void *)0xdeadbeef, "Pointer was modified %p.\n", data);
7232 
7233     data = NULL;
7234     hr = ID3D12Resource_Map(resource, 0, NULL, &data);
7235     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
7236     ok(data, "Got NULL pointer.\n");
7237     ID3D12Resource_Unmap(resource, 1, NULL);
7238     ID3D12Resource_Unmap(resource, 0, NULL);
7239 
7240     /* Passing NULL to Map should map, but not disclose the CPU VA to caller. */
7241     hr = ID3D12Resource_Map(resource, 0, NULL, NULL);
7242     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
7243     ID3D12Resource_Unmap(resource, 0, NULL);
7244 
7245     ID3D12Resource_Release(resource);
7246 
7247     refcount = ID3D12Device_Release(device);
7248     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
7249 }
7250 
test_map_placed_resources(void)7251 static void test_map_placed_resources(void)
7252 {
7253     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
7254     ID3D12GraphicsCommandList *command_list;
7255     ID3D12Heap *upload_heap, *readback_heap;
7256     D3D12_ROOT_PARAMETER root_parameters[2];
7257     D3D12_RESOURCE_DESC resource_desc;
7258     ID3D12Resource *readback_buffer;
7259     struct test_context_desc desc;
7260     struct resource_readback rb;
7261     struct test_context context;
7262     ID3D12Resource *uav_buffer;
7263     D3D12_HEAP_DESC heap_desc;
7264     ID3D12CommandQueue *queue;
7265     ID3D12Resource *cb[4];
7266     uint32_t *cb_data[4];
7267     ID3D12Device *device;
7268     D3D12_RANGE range;
7269     unsigned int i;
7270     uint32_t *ptr;
7271     HRESULT hr;
7272 
7273     STATIC_ASSERT(ARRAY_SIZE(cb) == ARRAY_SIZE(cb_data));
7274 
7275     static const DWORD ps_code[] =
7276     {
7277 #if 0
7278         uint offset;
7279         uint value;
7280 
7281         RWByteAddressBuffer u;
7282 
7283         void main()
7284         {
7285             u.Store(offset, value);
7286         }
7287 #endif
7288         0x43425844, 0x0dcbdd90, 0x7dad2857, 0x4ee149ee, 0x72a13d21, 0x00000001, 0x000000a4, 0x00000003,
7289         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7290         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000050, 0x00000050, 0x00000014, 0x0100086a,
7291         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300009d, 0x0011e000, 0x00000000, 0x090000a6,
7292         0x0011e012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0020801a, 0x00000000, 0x00000000,
7293         0x0100003e,
7294     };
7295     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
7296     static const uint32_t expected_values[] = {0xdead, 0xbeef, 0xfeed, 0xc0de};
7297 
7298     memset(&desc, 0, sizeof(desc));
7299     desc.no_root_signature = true;
7300     if (!init_test_context(&context, &desc))
7301         return;
7302     device = context.device;
7303     command_list = context.list;
7304     queue = context.queue;
7305 
7306     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
7307     root_parameters[0].Descriptor.ShaderRegister = 0;
7308     root_parameters[0].Descriptor.RegisterSpace = 0;
7309     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
7310     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
7311     root_parameters[1].Descriptor.ShaderRegister = 0;
7312     root_parameters[1].Descriptor.RegisterSpace = 0;
7313     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
7314     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
7315     root_signature_desc.pParameters = root_parameters;
7316     root_signature_desc.NumStaticSamplers = 0;
7317     root_signature_desc.pStaticSamplers = NULL;
7318     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
7319     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
7320     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
7321 
7322     context.pipeline_state = create_pipeline_state(device, context.root_signature, 0, NULL, &ps, NULL);
7323 
7324     heap_desc.SizeInBytes = ARRAY_SIZE(cb) * D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
7325     memset(&heap_desc.Properties, 0, sizeof(heap_desc.Properties));
7326     heap_desc.Properties.Type = D3D12_HEAP_TYPE_UPLOAD;
7327     heap_desc.Alignment = 0;
7328     heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
7329     hr = ID3D12Device_CreateHeap(device, &heap_desc, &IID_ID3D12Heap, (void **)&upload_heap);
7330     ok(hr == S_OK, "Failed to create heap, hr %#x.\n", hr);
7331 
7332     heap_desc.SizeInBytes = 1024;
7333     heap_desc.Properties.Type = D3D12_HEAP_TYPE_READBACK;
7334     hr = ID3D12Device_CreateHeap(device, &heap_desc, &IID_ID3D12Heap, (void **)&readback_heap);
7335     ok(hr == S_OK, "Failed to create heap, hr %#x.\n", hr);
7336 
7337     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
7338     resource_desc.Alignment = 0;
7339     resource_desc.Width = D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT;
7340     resource_desc.Height = 1;
7341     resource_desc.DepthOrArraySize = 1;
7342     resource_desc.MipLevels = 1;
7343     resource_desc.Format = DXGI_FORMAT_UNKNOWN;
7344     resource_desc.SampleDesc.Count = 1;
7345     resource_desc.SampleDesc.Quality = 0;
7346     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
7347     resource_desc.Flags = 0;
7348 
7349     for (i = 0; i < ARRAY_SIZE(cb); ++i)
7350     {
7351         hr = ID3D12Device_CreatePlacedResource(device, upload_heap,
7352                 i * D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,
7353                 &resource_desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL,
7354                 &IID_ID3D12Resource, (void **)&cb[i]);
7355         ok(hr == S_OK, "Failed to create placed resource %u, hr %#x.\n", i, hr);
7356     }
7357 
7358     resource_desc.Width = 1024;
7359     hr = ID3D12Device_CreatePlacedResource(device, readback_heap, 0,
7360             &resource_desc, D3D12_RESOURCE_STATE_COPY_DEST, NULL,
7361             &IID_ID3D12Resource, (void **)&readback_buffer);
7362     ok(hr == S_OK, "Failed to create placed resource, hr %#x.\n", hr);
7363 
7364     uav_buffer = create_default_buffer(device, resource_desc.Width,
7365             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
7366 
7367     for (i = 0; i < ARRAY_SIZE(cb); ++i)
7368     {
7369         hr = ID3D12Resource_Map(cb[i], 0, NULL, (void **)&cb_data[i]);
7370         ok(hr == S_OK, "Failed to map buffer %u, hr %#x.\n", i, hr);
7371     }
7372 
7373     hr = ID3D12Resource_Map(cb[0], 0, NULL, (void **)&ptr);
7374     ok(hr == S_OK, "Failed to map buffer, hr %#x.\n", hr);
7375     ok(ptr == cb_data[0], "Got map ptr %p, expected %p.\n", ptr, cb_data[0]);
7376     cb_data[0][0] = 0;
7377     cb_data[0][1] = expected_values[0];
7378     ID3D12Resource_Unmap(cb[0], 0, NULL);
7379     ID3D12Resource_Unmap(cb[0], 0, NULL);
7380     cb_data[0] = NULL;
7381 
7382     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
7383     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
7384     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
7385     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
7386     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
7387     ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView(command_list, 0,
7388             ID3D12Resource_GetGPUVirtualAddress(uav_buffer));
7389 
7390     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 1,
7391             ID3D12Resource_GetGPUVirtualAddress(cb[0]));
7392     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
7393 
7394     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 1,
7395             ID3D12Resource_GetGPUVirtualAddress(cb[2]));
7396     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
7397     cb_data[2][0] = 4;
7398     cb_data[2][1] = expected_values[1];
7399 
7400     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 1,
7401             ID3D12Resource_GetGPUVirtualAddress(cb[1]));
7402     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
7403     cb_data[1][0] = 8;
7404     cb_data[1][1] = expected_values[2];
7405 
7406     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 1,
7407             ID3D12Resource_GetGPUVirtualAddress(cb[3]));
7408     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
7409     cb_data[3][0] = 12;
7410     cb_data[3][1] = expected_values[3];
7411     range.Begin = 0;
7412     range.End = 2 * sizeof(uint32_t);
7413     ID3D12Resource_Unmap(cb[3], 0, &range);
7414     cb_data[3] = NULL;
7415 
7416     transition_resource_state(command_list, uav_buffer,
7417             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
7418     ID3D12GraphicsCommandList_CopyResource(command_list, readback_buffer, uav_buffer);
7419 
7420     get_buffer_readback_with_command_list(readback_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
7421     for (i = 0; i < ARRAY_SIZE(expected_values); ++i)
7422     {
7423         unsigned int value = get_readback_uint(&rb, i, 0, 0);
7424         ok(value == expected_values[i], "Got %#x, expected %#x at %u.\n", value, expected_values[i], i);
7425     }
7426     release_resource_readback(&rb);
7427 
7428     ID3D12Resource_Release(uav_buffer);
7429     ID3D12Resource_Release(readback_buffer);
7430     ID3D12Heap_Release(upload_heap);
7431     ID3D12Heap_Release(readback_heap);
7432     for (i = 0; i < ARRAY_SIZE(cb); ++i)
7433         ID3D12Resource_Release(cb[i]);
7434     destroy_test_context(&context);
7435 }
7436 
test_bundle_state_inheritance(void)7437 static void test_bundle_state_inheritance(void)
7438 {
7439     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
7440     ID3D12GraphicsCommandList *command_list, *bundle;
7441     ID3D12CommandAllocator *bundle_allocator;
7442     struct test_context context;
7443     struct resource_readback rb;
7444     ID3D12CommandQueue *queue;
7445     ID3D12Device *device;
7446     unsigned int x, y;
7447     HRESULT hr;
7448 
7449     if (!vkd3d_test_platform_is_windows())
7450     {
7451         /* FIXME: Avoid 2048 test todos. */
7452         skip("Bundles are not implemented yet.\n");
7453         return;
7454     }
7455 
7456     if (use_warp_device)
7457     {
7458         skip("Bundle state inheritance test crashes on WARP.\n");
7459         return;
7460     }
7461 
7462     if (!init_test_context(&context, NULL))
7463         return;
7464     device = context.device;
7465     command_list = context.list;
7466     queue = context.queue;
7467 
7468     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_BUNDLE,
7469             &IID_ID3D12CommandAllocator, (void **)&bundle_allocator);
7470     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
7471     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_BUNDLE,
7472             bundle_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&bundle);
7473     ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
7474 
7475     /* A bundle does not inherit the current pipeline state. */
7476     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
7477 
7478     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
7479     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
7480     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
7481     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
7482     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
7483     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
7484 
7485     ID3D12GraphicsCommandList_DrawInstanced(bundle, 3, 1, 0, 0);
7486     hr = ID3D12GraphicsCommandList_Close(bundle);
7487     ok(SUCCEEDED(hr), "Failed to close bundle, hr %#x.\n", hr);
7488 
7489     ID3D12GraphicsCommandList_ExecuteBundle(command_list, bundle);
7490 
7491     transition_resource_state(command_list, context.render_target,
7492             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
7493 
7494     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
7495     for (y = 0; y < rb.height; ++y)
7496     {
7497         for (x = 0; x < rb.width; ++x)
7498         {
7499            unsigned int v = get_readback_uint(&rb, x, y, 0);
7500            /* This works on AMD. */
7501            ok(v == 0xffffffff || v == 0xff00ff00, "Got unexpected value 0x%08x at (%u, %u).\n", v, x, y);
7502         }
7503     }
7504     release_resource_readback(&rb);
7505 
7506     reset_command_list(command_list, context.allocator);
7507     reset_command_list(bundle, bundle_allocator);
7508 
7509     /* A bundle does not inherit the current primitive topology. */
7510     transition_resource_state(command_list, context.render_target,
7511             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
7512     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
7513 
7514     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
7515     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
7516     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
7517     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
7518     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
7519     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
7520 
7521     ID3D12GraphicsCommandList_SetPipelineState(bundle, context.pipeline_state);
7522     ID3D12GraphicsCommandList_DrawInstanced(bundle, 3, 1, 0, 0);
7523     hr = ID3D12GraphicsCommandList_Close(bundle);
7524     ok(SUCCEEDED(hr), "Failed to close bundle, hr %#x.\n", hr);
7525 
7526     ID3D12GraphicsCommandList_ExecuteBundle(command_list, bundle);
7527 
7528     transition_resource_state(command_list, context.render_target,
7529             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
7530 
7531     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
7532     for (y = 0; y < rb.height; ++y)
7533     {
7534         for (x = 0; x < rb.width; ++x)
7535         {
7536            unsigned int v = get_readback_uint(&rb, x, y, 0);
7537            /* This works on AMD, even though the debug layer says that the primitive topology is undefined. */
7538            ok(v == 0xffffffff || v == 0xff00ff00, "Got unexpected value 0x%08x at (%u, %u).\n", v, x, y);
7539         }
7540     }
7541     release_resource_readback(&rb);
7542 
7543     reset_command_list(command_list, context.allocator);
7544     reset_command_list(bundle, bundle_allocator);
7545 
7546     /* A bundle inherit all other states. */
7547     transition_resource_state(command_list, context.render_target,
7548             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
7549     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
7550 
7551     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
7552     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
7553     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
7554     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
7555 
7556     ID3D12GraphicsCommandList_SetPipelineState(bundle, context.pipeline_state);
7557     ID3D12GraphicsCommandList_IASetPrimitiveTopology(bundle, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
7558     ID3D12GraphicsCommandList_DrawInstanced(bundle, 3, 1, 0, 0);
7559     hr = ID3D12GraphicsCommandList_Close(bundle);
7560     ok(SUCCEEDED(hr), "Failed to close bundle, hr %#x.\n", hr);
7561 
7562     ID3D12GraphicsCommandList_ExecuteBundle(command_list, bundle);
7563 
7564     transition_resource_state(command_list, context.render_target,
7565             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
7566     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
7567 
7568     reset_command_list(command_list, context.allocator);
7569     reset_command_list(bundle, bundle_allocator);
7570 
7571     /* All state that is set in a bundle affects a command list. */
7572     transition_resource_state(command_list, context.render_target,
7573             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
7574     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
7575     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
7576     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
7577     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
7578 
7579     ID3D12GraphicsCommandList_SetGraphicsRootSignature(bundle, context.root_signature);
7580     ID3D12GraphicsCommandList_SetPipelineState(bundle, context.pipeline_state);
7581     ID3D12GraphicsCommandList_IASetPrimitiveTopology(bundle, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
7582     hr = ID3D12GraphicsCommandList_Close(bundle);
7583     ok(SUCCEEDED(hr), "Failed to close bundle, hr %#x.\n", hr);
7584 
7585     ID3D12GraphicsCommandList_ExecuteBundle(command_list, bundle);
7586 
7587     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
7588 
7589     transition_resource_state(command_list, context.render_target,
7590             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
7591     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
7592 
7593     ID3D12CommandAllocator_Release(bundle_allocator);
7594     ID3D12GraphicsCommandList_Release(bundle);
7595     destroy_test_context(&context);
7596 }
7597 
test_shader_instructions(void)7598 static void test_shader_instructions(void)
7599 {
7600     struct named_shader
7601     {
7602         const char *name;
7603         const void *code;
7604         size_t size;
7605     };
7606 
7607     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
7608     ID3D12GraphicsCommandList *command_list;
7609     const struct named_shader *current_ps;
7610     struct test_context_desc desc;
7611     D3D12_SHADER_BYTECODE shader;
7612     struct test_context context;
7613     ID3D12CommandQueue *queue;
7614     ID3D12Resource *cb;
7615     unsigned int i;
7616     HRESULT hr;
7617 
7618     static const DWORD ps_div_code[] =
7619     {
7620 #if 0
7621         float4 src0;
7622         float4 src1;
7623 
7624         void main(out float4 dst : SV_Target)
7625         {
7626             dst.x = src0.x / src1.x;
7627             dst.yzw = (float3)0;
7628         }
7629 #endif
7630         0x43425844, 0x19578813, 0xb1e4de1e, 0x3adee1dc, 0x478cd5d3, 0x00000001, 0x000000e8, 0x00000003,
7631         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7632         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7633         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000070, 0x00000050, 0x0000001c,
7634         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
7635         0x0900000e, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0020800a, 0x00000000,
7636         0x00000001, 0x08000036, 0x001020e2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
7637         0x00000000, 0x0100003e,
7638     };
7639     static const struct named_shader ps_div = {"div", ps_div_code, sizeof(ps_div_code)};
7640     static const DWORD ps_dot2_code[] =
7641     {
7642 #if 0
7643         float4 src0;
7644         float4 src1;
7645 
7646         void main(out float4 dst : SV_Target)
7647         {
7648             dst.x = dot(src0.xy, src1.xy);
7649             dst.yzw = (float3)0;
7650         }
7651 #endif
7652         0x43425844, 0x3621a1c7, 0x79d3be21, 0x9f14138c, 0x9f5506f2, 0x00000001, 0x000000e8, 0x00000003,
7653         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7654         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7655         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000070, 0x00000050, 0x0000001c,
7656         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
7657         0x0900000f, 0x00102012, 0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x00208046, 0x00000000,
7658         0x00000001, 0x08000036, 0x001020e2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
7659         0x00000000, 0x0100003e,
7660     };
7661     static struct named_shader ps_dot2 = {"dot2", ps_dot2_code, sizeof(ps_dot2_code)};
7662     static const DWORD ps_dot3_code[] =
7663     {
7664 #if 0
7665         float4 src0;
7666         float3 src1;
7667 
7668         float4 main() : SV_Target
7669         {
7670             return dot(src0, src1);
7671         }
7672 #endif
7673         0x43425844, 0xa75a4a95, 0x5d09936e, 0xdc5c694f, 0x68b6b04f, 0x00000001, 0x000000c8, 0x00000003,
7674         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7675         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7676         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000050, 0x00000050, 0x00000014,
7677         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
7678         0x09000010, 0x001020f2, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x00208246, 0x00000000,
7679         0x00000001, 0x0100003e,
7680     };
7681     static struct named_shader ps_dot3 = {"dot3", ps_dot3_code, sizeof(ps_dot3_code)};
7682     static const DWORD ps_eq_code[] =
7683     {
7684 #if 0
7685         float4 src0;
7686         float4 src1;
7687 
7688         void main(out float4 dst : SV_Target)
7689         {
7690             dst = (uint4)0;
7691             if (src0.x == src1.x)
7692                 dst.x = asfloat(0xffffffff);
7693         }
7694 #endif
7695         0x43425844, 0x7bce1728, 0xa7d5d0f0, 0xaef5bc00, 0x7bb6b161, 0x00000001, 0x000000e8, 0x00000003,
7696         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7697         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7698         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000070, 0x00000050, 0x0000001c,
7699         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
7700         0x09000018, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0020800a, 0x00000000,
7701         0x00000001, 0x08000036, 0x001020e2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
7702         0x00000000, 0x0100003e,
7703     };
7704     static struct named_shader ps_eq = {"eq", ps_eq_code, sizeof(ps_eq_code)};
7705     static const DWORD ps_ne_code[] =
7706     {
7707 #if 0
7708         float4 src0;
7709         float4 src1;
7710 
7711         void main(out float4 dst : SV_Target)
7712         {
7713             dst = (uint4)0;
7714             if (src0.x != src1.x)
7715                 dst.x = asfloat(0xffffffff);
7716         }
7717 #endif
7718         0x43425844, 0x5bbb7f90, 0x1a44971c, 0x4ee3d92e, 0x149ceecf, 0x00000001, 0x000000e8, 0x00000003,
7719         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7720         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7721         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000070, 0x00000050, 0x0000001c,
7722         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
7723         0x09000039, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0020800a, 0x00000000,
7724         0x00000001, 0x08000036, 0x001020e2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
7725         0x00000000, 0x0100003e,
7726     };
7727     static struct named_shader ps_ne = {"ne", ps_ne_code, sizeof(ps_ne_code)};
7728     static const DWORD ps_if_code[] =
7729     {
7730         /* compiled with /Gfp option */
7731 #if 0
7732         float4 src0;
7733 
7734         void main(out float4 dst : SV_Target)
7735         {
7736             if (src0.x)
7737                 dst = float4(0, 1, 0, 1);
7738             else
7739                 dst = float4(1, 0, 0, 1);
7740         }
7741 #endif
7742         0x43425844, 0xfe5b6a47, 0x123f8934, 0xfa5910fe, 0x497aad93, 0x00000001, 0x0000012c, 0x00000003,
7743         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7744         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7745         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000b4, 0x00000050, 0x0000002d,
7746         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
7747         0x02000068, 0x00000001, 0x0b000039, 0x00100012, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
7748         0x00000000, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0304001f, 0x0010000a, 0x00000000,
7749         0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000,
7750         0x01000012, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x3f800000, 0x00000000, 0x00000000,
7751         0x3f800000, 0x01000015, 0x0100003e
7752     };
7753     static struct named_shader ps_if = {"if", ps_if_code, sizeof(ps_if_code)};
7754     static const DWORD ps_if_return_code[] =
7755     {
7756 #if 0
7757         float4 src0;
7758 
7759         void main(out float4 dst : SV_Target)
7760         {
7761             dst = (float4)0;
7762             if (src0.x < 4)
7763                 return;
7764             dst.x = 1;
7765             if (src0.y < 4)
7766                 return;
7767             dst.y = 1;
7768             if (src0.z >= 4)
7769                 return;
7770             dst.z = 1;
7771             if (src0.w <= src0.x)
7772                 return;
7773             dst.w = 1;
7774         }
7775 #endif
7776         0x43425844, 0xa2797349, 0xd0a60aee, 0x7ae89f23, 0xf9681bfe, 0x00000001, 0x00000220, 0x00000003,
7777         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7778         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7779         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000001a8, 0x00000050, 0x0000006a,
7780         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
7781         0x02000068, 0x00000001, 0x08000031, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000,
7782         0x00004001, 0x40800000, 0x0304001f, 0x0010000a, 0x00000000, 0x08000036, 0x001020f2, 0x00000000,
7783         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e, 0x01000015, 0x08000031,
7784         0x00100012, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x00004001, 0x40800000, 0x0304001f,
7785         0x0010000a, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x3f800000, 0x00000000,
7786         0x00000000, 0x00000000, 0x0100003e, 0x01000015, 0x0800001d, 0x00100012, 0x00000000, 0x0020802a,
7787         0x00000000, 0x00000000, 0x00004001, 0x40800000, 0x0304001f, 0x0010000a, 0x00000000, 0x08000036,
7788         0x001020f2, 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x0100003e,
7789         0x01000015, 0x0900001d, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0020803a,
7790         0x00000000, 0x00000000, 0x0304001f, 0x0010000a, 0x00000000, 0x08000036, 0x001020f2, 0x00000000,
7791         0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x0100003e, 0x01000015, 0x08000036,
7792         0x001020f2, 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0100003e,
7793     };
7794     static struct named_shader ps_if_return = {"if_return", ps_if_return_code, sizeof(ps_if_return_code)};
7795     static const DWORD ps_nested_if_code[] =
7796     {
7797         /* compiled with /Gfp option */
7798 #if 0
7799         float4 src0;
7800 
7801         void main(out float4 dst : SV_Target)
7802         {
7803             if (src0.x)
7804             {
7805                 if (src0.y)
7806                     dst = float4(0, 1, 0, 1);
7807                 else
7808                     dst = float4(0, 0, 1, 1);
7809             }
7810             else
7811             {
7812                 if (src0.z)
7813                     dst = float4(1, 0, 0, 1);
7814                 else
7815                     dst = float4(0, 0, 0, 1);
7816             }
7817         }
7818 #endif
7819         0x43425844, 0x35e50e88, 0x68c45bdd, 0x0dc60de1, 0x4bc29735, 0x00000001, 0x000001ec, 0x00000003,
7820         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7821         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7822         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000174, 0x00000050, 0x0000005d,
7823         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
7824         0x02000068, 0x00000001, 0x0b000039, 0x00100012, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
7825         0x00000000, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0304001f, 0x0010000a, 0x00000000,
7826         0x0b000039, 0x00100012, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
7827         0x0020801a, 0x00000000, 0x00000000, 0x0304001f, 0x0010000a, 0x00000000, 0x08000036, 0x001020f2,
7828         0x00000000, 0x00004002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x01000012, 0x08000036,
7829         0x001020f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x01000015,
7830         0x01000012, 0x0b000039, 0x00100012, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
7831         0x00000000, 0x0020802a, 0x00000000, 0x00000000, 0x0304001f, 0x0010000a, 0x00000000, 0x08000036,
7832         0x001020f2, 0x00000000, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x01000012,
7833         0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,
7834         0x01000015, 0x01000015, 0x0100003e,
7835     };
7836     static struct named_shader ps_nested_if = {"nested_if", ps_nested_if_code, sizeof(ps_nested_if_code)};
7837     static const DWORD ps_loop_break_code[] =
7838     {
7839 #if 0
7840         float4 src0;
7841 
7842         void main(out float4 dst : SV_Target)
7843         {
7844             float tmp = 0.0f;
7845             for (int i = 0; i < src0.x; ++i)
7846             {
7847                 if (i == src0.y)
7848                 {
7849                     tmp = 1.0f;
7850                     break;
7851                 }
7852                 tmp += 1.0f;
7853             }
7854 
7855             dst = float4(tmp, 0, 0, 0);
7856         }
7857 #endif
7858         0x43425844, 0xbd9dabbd, 0xe56cab2a, 0xfd37cd76, 0x5dd181c4, 0x00000001, 0x000001c8, 0x00000003,
7859         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7860         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7861         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000150, 0x00000050, 0x00000054,
7862         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
7863         0x02000068, 0x00000001, 0x08000036, 0x00100032, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
7864         0x00000000, 0x00000000, 0x01000030, 0x0500002b, 0x00100042, 0x00000000, 0x0010001a, 0x00000000,
7865         0x0800001d, 0x00100082, 0x00000000, 0x0010002a, 0x00000000, 0x0020800a, 0x00000000, 0x00000000,
7866         0x03040003, 0x0010003a, 0x00000000, 0x08000018, 0x00100042, 0x00000000, 0x0010002a, 0x00000000,
7867         0x0020801a, 0x00000000, 0x00000000, 0x0304001f, 0x0010002a, 0x00000000, 0x05000036, 0x00100012,
7868         0x00000000, 0x00004001, 0x3f800000, 0x01000002, 0x01000015, 0x07000000, 0x00100012, 0x00000000,
7869         0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0700001e, 0x00100022, 0x00000000, 0x0010001a,
7870         0x00000000, 0x00004001, 0x00000001, 0x01000016, 0x05000036, 0x00102012, 0x00000000, 0x0010000a,
7871         0x00000000, 0x08000036, 0x001020e2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
7872         0x00000000, 0x0100003e,
7873     };
7874     static struct named_shader ps_loop_break = {"loop_break", ps_loop_break_code, sizeof(ps_loop_break_code)};
7875     static const DWORD ps_loop_ret_code[] =
7876     {
7877 #if 0
7878         float4 src0;
7879 
7880         void main(out float4 dst : SV_Target)
7881         {
7882             float tmp = 0.0f;
7883             for (int i = 0; i < src0.x; ++i)
7884             {
7885                 if (i == src0.y)
7886                 {
7887                     dst = 1;
7888                     return;
7889                 }
7890                 tmp += 1.0f;
7891             }
7892 
7893             dst = float4(tmp, 0, 0, 0);
7894         }
7895 #endif
7896         0x43425844, 0xb327003a, 0x5812a5f6, 0xb5a78d54, 0xa72a8db8, 0x00000001, 0x000001d4, 0x00000003,
7897         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7898         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7899         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000015c, 0x00000050, 0x00000057,
7900         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
7901         0x02000068, 0x00000001, 0x08000036, 0x00100032, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
7902         0x00000000, 0x00000000, 0x01000030, 0x0500002b, 0x00100042, 0x00000000, 0x0010001a, 0x00000000,
7903         0x0800001d, 0x00100082, 0x00000000, 0x0010002a, 0x00000000, 0x0020800a, 0x00000000, 0x00000000,
7904         0x03040003, 0x0010003a, 0x00000000, 0x08000018, 0x00100042, 0x00000000, 0x0010002a, 0x00000000,
7905         0x0020801a, 0x00000000, 0x00000000, 0x0304001f, 0x0010002a, 0x00000000, 0x08000036, 0x001020f2,
7906         0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0100003e, 0x01000015,
7907         0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0700001e,
7908         0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x00000001, 0x01000016, 0x05000036,
7909         0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x08000036, 0x001020e2, 0x00000000, 0x00004002,
7910         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e,
7911     };
7912     static struct named_shader ps_loop_ret = {"loop_ret", ps_loop_ret_code, sizeof(ps_loop_ret_code)};
7913     static const DWORD ps_breakc_nz_code[] =
7914     {
7915 #if 0
7916         float4 main() : SV_TARGET
7917         {
7918             uint counter = 0;
7919 
7920             for (uint i = 0; i < 255; ++i)
7921                 ++counter;
7922 
7923             if (counter == 255)
7924                 return float4(0.0f, 1.0f, 0.0f, 1.0f);
7925             else
7926                 return float4(1.0f, 0.0f, 0.0f, 1.0f);
7927         }
7928 #endif
7929         0x43425844, 0x065ac80a, 0x24369e7e, 0x218d5dc1, 0x3532868c, 0x00000001, 0x00000188, 0x00000003,
7930         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7931         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7932         0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000110, 0x00000040, 0x00000044,
7933         0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x08000036, 0x00100032, 0x00000000,
7934         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01000030, 0x07000050, 0x00100042,
7935         0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x000000ff, 0x03040003, 0x0010002a, 0x00000000,
7936         0x0a00001e, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00004002, 0x00000001, 0x00000001,
7937         0x00000000, 0x00000000, 0x01000016, 0x07000020, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
7938         0x00004001, 0x000000ff, 0x0304001f, 0x0010000a, 0x00000000, 0x08000036, 0x001020f2, 0x00000000,
7939         0x00004002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x0100003e, 0x01000012, 0x08000036,
7940         0x001020f2, 0x00000000, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e,
7941         0x01000015, 0x0100003e,
7942     };
7943     static struct named_shader ps_breakc_nz = {"breakc_nz", ps_breakc_nz_code, sizeof(ps_breakc_nz_code)};
7944     static const DWORD ps_breakc_z_code[] =
7945     {
7946 #if 0
7947         float4 main() : SV_TARGET
7948         {
7949             uint counter = 0;
7950 
7951             for (int i = 0, j = 254; i < 255 && j >= 0; ++i, --j)
7952                 ++counter;
7953 
7954             if (counter == 255)
7955                 return float4(0.0f, 1.0f, 0.0f, 1.0f);
7956             else
7957                 return float4(1.0f, 0.0f, 0.0f, 1.0f);
7958         }
7959 #endif
7960         0x43425844, 0x687406ef, 0x7bdeb7d1, 0xb3282292, 0x934a9101, 0x00000001, 0x000001c0, 0x00000003,
7961         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7962         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7963         0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000148, 0x00000040, 0x00000052,
7964         0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x08000036, 0x00100072, 0x00000000,
7965         0x00004002, 0x00000000, 0x00000000, 0x000000fe, 0x00000000, 0x01000030, 0x07000022, 0x00100082,
7966         0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x000000ff, 0x07000021, 0x00100012, 0x00000001,
7967         0x0010002a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100082, 0x00000000, 0x0010003a,
7968         0x00000000, 0x0010000a, 0x00000001, 0x03000003, 0x0010003a, 0x00000000, 0x0a00001e, 0x00100072,
7969         0x00000000, 0x00100246, 0x00000000, 0x00004002, 0x00000001, 0x00000001, 0xffffffff, 0x00000000,
7970         0x01000016, 0x07000020, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x000000ff,
7971         0x0304001f, 0x0010000a, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000,
7972         0x3f800000, 0x00000000, 0x3f800000, 0x0100003e, 0x01000012, 0x08000036, 0x001020f2, 0x00000000,
7973         0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e, 0x01000015, 0x0100003e,
7974     };
7975     static struct named_shader ps_breakc_z = {"breakc_z", ps_breakc_z_code, sizeof(ps_breakc_z_code)};
7976     static const DWORD ps_continue_code[] =
7977     {
7978 #if 0
7979         float4 main() : SV_TARGET
7980         {
7981             uint counter = 0;
7982 
7983             for (uint i = 0; i < 255; ++i)
7984             {
7985                 if (i == 10)
7986                     continue;
7987                 ++counter;
7988             }
7989 
7990             return float4(counter, 0.0f, 0.0f, 0.0f);
7991         }
7992 #endif
7993         0x43425844, 0x8cab8e1f, 0x527560f9, 0x04eb888b, 0x20d89b05, 0x00000001, 0x000001c4, 0x00000003,
7994         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
7995         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
7996         0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x58454853, 0x0000014c, 0x00000050, 0x00000053,
7997         0x0100086a, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x05000036, 0x00100022,
7998         0x00000000, 0x00004001, 0x0000000b, 0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000,
7999         0x00000000, 0x00000000, 0x00000000, 0x01000030, 0x07000050, 0x00100012, 0x00000001, 0x0010002a,
8000         0x00000000, 0x00004001, 0x000000ff, 0x03040003, 0x0010000a, 0x00000001, 0x07000020, 0x00100012,
8001         0x00000001, 0x0010002a, 0x00000000, 0x00004001, 0x0000000a, 0x0304001f, 0x0010000a, 0x00000001,
8002         0x05000036, 0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x05000036, 0x001000c2, 0x00000000,
8003         0x00100156, 0x00000000, 0x01000007, 0x01000015, 0x0700001e, 0x00100082, 0x00000000, 0x0010003a,
8004         0x00000000, 0x00004001, 0x00000001, 0x0700001e, 0x00100042, 0x00000000, 0x0010002a, 0x00000000,
8005         0x00004001, 0x00000001, 0x01000016, 0x05000056, 0x00102012, 0x00000000, 0x0010003a, 0x00000000,
8006         0x08000036, 0x001020e2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
8007         0x0100003e,
8008     };
8009     static struct named_shader ps_continue = {"continue", ps_continue_code, sizeof(ps_continue_code)};
8010     static const DWORD ps_continuec_nz_code[] =
8011     {
8012 #if 0
8013         float4 main() : SV_TARGET
8014         {
8015             uint counter = 0;
8016 
8017             for (uint i = 0; i < 255; ++i)
8018             {
8019                 ++counter;
8020                 if (i % 2 == 0)
8021                     continue;
8022                 ++counter;
8023                 if (i != 0)
8024                     continue;
8025                 ++counter;
8026             }
8027 
8028             return float4(counter, 0.0f, 0.0f, 0.0f);
8029         }
8030 #endif
8031         /* compiled with /Gfa */
8032         0x43425844, 0xf35d8ce6, 0x54988f56, 0x5848863e, 0xa1618498, 0x00000001, 0x00000278, 0x00000003,
8033         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8034         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8035         0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x58454853, 0x00000200, 0x00000050, 0x00000080,
8036         0x0100086a, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x08000036, 0x00100032,
8037         0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01000030, 0x07000050,
8038         0x00100042, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x000000ff, 0x03040003, 0x0010002a,
8039         0x00000000, 0x0700001e, 0x00100042, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000001,
8040         0x07000001, 0x00100082, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x00000001, 0x0700001e,
8041         0x00100012, 0x00000001, 0x0010001a, 0x00000000, 0x00004001, 0x00000001, 0x09000037, 0x00100022,
8042         0x00000001, 0x0010003a, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000001, 0x05000036,
8043         0x00100012, 0x00000000, 0x0010002a, 0x00000000, 0x05000036, 0x00100022, 0x00000000, 0x0010001a,
8044         0x00000001, 0x03000008, 0x0010003a, 0x00000000, 0x0700001e, 0x00100042, 0x00000000, 0x0010000a,
8045         0x00000000, 0x00004001, 0x00000002, 0x07000027, 0x00100082, 0x00000000, 0x0010001a, 0x00000000,
8046         0x00004001, 0x00000000, 0x09000037, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a,
8047         0x00000001, 0x00004001, 0x00000000, 0x05000036, 0x00100032, 0x00000000, 0x00100a66, 0x00000000,
8048         0x03040008, 0x0010003a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
8049         0x00004001, 0x00000003, 0x05000036, 0x00100022, 0x00000000, 0x0010000a, 0x00000001, 0x01000016,
8050         0x05000056, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x08000036, 0x001020e2, 0x00000000,
8051         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e,
8052     };
8053     static struct named_shader ps_continuec_nz = {"continuec_nz", ps_continuec_nz_code, sizeof(ps_continuec_nz_code)};
8054     static const DWORD ps_retc_nz_code[] =
8055     {
8056 #if 0
8057         float src;
8058 
8059         float4 main() : SV_TARGET
8060         {
8061             for (int i = 0; i < 255; ++i)
8062             {
8063                 if (i == src)
8064                     return float4(1, 0, 0, 0);
8065             }
8066 
8067             return 0;
8068         }
8069 #endif
8070         /* compiled with /Gfa */
8071         0x43425844, 0xf829c302, 0xf21361cb, 0x963b87e9, 0x92f9470e, 0x00000001, 0x00000188, 0x00000003,
8072         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8073         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8074         0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000110, 0x00000040, 0x00000044,
8075         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
8076         0x00000001, 0x05000036, 0x00100012, 0x00000000, 0x00004001, 0x00000000, 0x01000030, 0x07000021,
8077         0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x000000ff, 0x03040003, 0x0010001a,
8078         0x00000000, 0x0500002b, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x08000018, 0x00100022,
8079         0x00000000, 0x0010001a, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x08000036, 0x001020f2,
8080         0x00000000, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x0304003f, 0x0010001a,
8081         0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000001,
8082         0x01000016, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
8083         0x00000000, 0x0100003e,
8084     };
8085     static struct named_shader ps_retc_nz = {"retc_nz", ps_retc_nz_code, sizeof(ps_retc_nz_code)};
8086     static const DWORD ps_src_modifiers_code[] =
8087     {
8088 #if 0
8089         float4 src0;
8090 
8091         void main(out float4 dst : SV_Target)
8092         {
8093             dst.x = -src0.x;
8094             dst.y = abs(src0.y);
8095             dst.zw = -abs(src0.zw);
8096         }
8097 #endif
8098         0x43425844, 0xa5f66fa8, 0xd430e547, 0x1cd28240, 0xaf5bc0f4, 0x00000001, 0x000000f8, 0x00000003,
8099         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8100         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8101         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000080, 0x00000050, 0x00000020,
8102         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8103         0x07000036, 0x00102012, 0x00000000, 0x8020800a, 0x00000041, 0x00000000, 0x00000000, 0x07000036,
8104         0x00102022, 0x00000000, 0x8020801a, 0x00000081, 0x00000000, 0x00000000, 0x07000036, 0x001020c2,
8105         0x00000000, 0x80208ea6, 0x000000c1, 0x00000000, 0x00000000, 0x0100003e,
8106     };
8107     static struct named_shader ps_src_modifiers = {"src_modifiers", ps_src_modifiers_code, sizeof(ps_src_modifiers_code)};
8108     static const DWORD ps_sat_code[] =
8109     {
8110 #if 0
8111         float4 src;
8112 
8113         void main(out float4 dst : SV_Target)
8114         {
8115             dst = clamp(src, 0, 1);
8116         }
8117 #endif
8118         0x43425844, 0x50af2f8b, 0xaadad7cd, 0x77815f01, 0x612ec066, 0x00000001, 0x000000bc, 0x00000003,
8119         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8120         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8121         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000044, 0x00000050, 0x00000011,
8122         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8123         0x06002036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e,
8124     };
8125     static struct named_shader ps_sat = {"sat", ps_sat_code, sizeof(ps_sat_code)};
8126     static const DWORD ps_min_max_code[] =
8127     {
8128 #if 0
8129         float4 src0;
8130         float4 src1;
8131 
8132         void main(out float4 dst : SV_Target)
8133         {
8134             dst = (float4)0;
8135             dst.x = min(src0.x, src1.x);
8136             dst.y = max(src0.x, src1.x);
8137         }
8138 #endif
8139         0x43425844, 0xb570ee39, 0xcf84fe48, 0x7fa59ede, 0x6151def2, 0x00000001, 0x0000010c, 0x00000003,
8140         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8141         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8142         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000094, 0x00000050, 0x00000025,
8143         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
8144         0x09000033, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0020800a, 0x00000000,
8145         0x00000001, 0x09000034, 0x00102022, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0020800a,
8146         0x00000000, 0x00000001, 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
8147         0x00000000, 0x00000000, 0x0100003e,
8148     };
8149     static struct named_shader ps_min_max = {"min_max", ps_min_max_code, sizeof(ps_min_max_code)};
8150     static const DWORD ps_ftou_code[] =
8151     {
8152 #if 0
8153         float src;
8154 
8155         void main(out float4 dst : SV_Target)
8156         {
8157             dst = asfloat(uint4(src, -src, 0, 0));
8158         }
8159 #endif
8160         0x43425844, 0x7a61c2fa, 0x4f20de14, 0x3492a5ae, 0x0a1fdc98, 0x00000001, 0x000000f8, 0x00000003,
8161         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8162         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8163         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000080, 0x00000050, 0x00000020,
8164         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8165         0x0600001c, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0700001c, 0x00102022,
8166         0x00000000, 0x8020800a, 0x00000041, 0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000000,
8167         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e,
8168     };
8169     static struct named_shader ps_ftou = {"ftou", ps_ftou_code, sizeof(ps_ftou_code)};
8170     static const DWORD ps_ftoi_code[] =
8171     {
8172 #if 0
8173         float src;
8174 
8175         void main(out float4 dst : SV_Target)
8176         {
8177             dst = asfloat(int4(src, -src, 0, 0));
8178         }
8179 #endif
8180         0x43425844, 0x2737f059, 0x5a2faecc, 0x7eab1956, 0xf96357b5, 0x00000001, 0x000000f8, 0x00000003,
8181         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8182         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8183         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000080, 0x00000050, 0x00000020,
8184         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8185         0x0600001b, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0700001b, 0x00102022,
8186         0x00000000, 0x8020800a, 0x00000041, 0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000000,
8187         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e,
8188     };
8189     static struct named_shader ps_ftoi = {"ftoi", ps_ftoi_code, sizeof(ps_ftoi_code)};
8190     static const DWORD ps_round_code[] =
8191     {
8192 #if 0
8193         float src0;
8194 
8195         void main(out float4 dst : SV_Target)
8196         {
8197             dst.x = floor(src0);
8198             dst.y = ceil(src0);
8199             dst.z = trunc(src0);
8200             dst.w = 0;
8201         }
8202 #endif
8203         0x43425844, 0x44e2c554, 0x216a8c83, 0x87e90dd8, 0x3fde3e57, 0x00000001, 0x00000100, 0x00000003,
8204         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8205         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8206         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000088, 0x00000050, 0x00000022,
8207         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8208         0x06000041, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x06000042, 0x00102022,
8209         0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x06000043, 0x00102042, 0x00000000, 0x0020800a,
8210         0x00000000, 0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x00004001, 0x00000000, 0x0100003e,
8211     };
8212     static struct named_shader ps_round = {"round", ps_round_code, sizeof(ps_round_code)};
8213     static const DWORD ps_round_ne_code[] =
8214     {
8215 #if 0
8216         float4 src0;
8217 
8218         void main(out float4 dst : SV_Target)
8219         {
8220             dst = round(src0);
8221         }
8222 #endif
8223         0x43425844, 0xa2be1ad3, 0xf1389007, 0xc8221829, 0xcbef8ed0, 0x00000001, 0x000000bc, 0x00000003,
8224         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8225         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8226         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000044, 0x00000050, 0x00000011,
8227         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8228         0x06000040, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e,
8229     };
8230     static struct named_shader ps_round_ne = {"round_ne", ps_round_ne_code, sizeof(ps_round_ne_code)};
8231     static const DWORD ps_frc_code[] =
8232     {
8233 #if 0
8234         float src;
8235 
8236         void main(out float4 dst : SV_Target)
8237         {
8238             dst = 0;
8239             dst.x = frac(src);
8240             dst.y = frac(-src);
8241         }
8242 #endif
8243         0x43425844, 0xd52bc741, 0xda411d9a, 0x199054a2, 0x7461462d, 0x00000001, 0x000000f8, 0x00000003,
8244         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8245         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8246         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000080, 0x00000050, 0x00000020,
8247         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8248         0x0600001a, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0700001a, 0x00102022,
8249         0x00000000, 0x8020800a, 0x00000041, 0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000000,
8250         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e,
8251     };
8252     static struct named_shader ps_frc = {"frc", ps_frc_code, sizeof(ps_frc_code)};
8253     static const DWORD ps_exp_code[] =
8254     {
8255 #if 0
8256         float src;
8257 
8258         void main(out float4 dst : SV_Target)
8259         {
8260             dst = 0;
8261             dst.x = exp2(src);
8262         }
8263 #endif
8264         0x43425844, 0xa742b300, 0x10b64393, 0x7827fc4a, 0x328b8db5, 0x00000001, 0x000000dc, 0x00000003,
8265         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8266         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8267         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000064, 0x00000050, 0x00000019,
8268         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8269         0x06000019, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x08000036, 0x001020e2,
8270         0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e,
8271     };
8272     static struct named_shader ps_exp = {"exp", ps_exp_code, sizeof(ps_exp_code)};
8273     static const DWORD ps_log_code[] =
8274     {
8275 #if 0
8276         float src;
8277 
8278         void main(out float4 dst : SV_Target)
8279         {
8280             dst = 0;
8281             dst.x = log2(src);
8282         }
8283 #endif
8284         0x43425844, 0x2f1cc195, 0x6cc7d061, 0xe63df3b1, 0x9c68b968, 0x00000001, 0x000000dc, 0x00000003,
8285         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8286         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8287         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000064, 0x00000050, 0x00000019,
8288         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8289         0x0600002f, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x08000036, 0x001020e2,
8290         0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e,
8291     };
8292     static struct named_shader ps_log = {"log", ps_log_code, sizeof(ps_log_code)};
8293     static const DWORD ps_rcp_code[] =
8294     {
8295 #if 0
8296         float4 src;
8297 
8298         void main(out float4 dst : SV_Target)
8299         {
8300             dst = 0;
8301             dst.x = rcp(src.x);
8302         }
8303 #endif
8304         0x43425844, 0x3b0ab43e, 0xff4dcb50, 0x22531bf6, 0xe44bbc8c, 0x00000001, 0x000000dc, 0x00000003,
8305         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8306         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8307         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000064, 0x00000050, 0x00000019,
8308         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8309         0x06000081, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x08000036, 0x001020e2,
8310         0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e,
8311     };
8312     static struct named_shader ps_rcp = {"rcp", ps_rcp_code, sizeof(ps_rcp_code)};
8313     static const DWORD ps_rcp_vector_code[] =
8314     {
8315 #if 0
8316         float4 src;
8317 
8318         void main(out float4 dst : SV_Target)
8319         {
8320             dst.xyzw = rcp(src.xyzw);
8321         }
8322 #endif
8323         0x43425844, 0x4952e20e, 0x859b9f18, 0x7a31907a, 0x3f1cc4af, 0x00000001, 0x000000bc, 0x00000003,
8324         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8325         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8326         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000044, 0x00000050, 0x00000011,
8327         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8328         0x06000081, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e,
8329     };
8330     static struct named_shader ps_rcp_vector = {"rcp_vector", ps_rcp_vector_code, sizeof(ps_rcp_vector_code)};
8331     static const DWORD ps_sincos_code[] =
8332     {
8333 #if 0
8334         float2 src0;
8335 
8336         void main(out float4 dst : SV_Target)
8337         {
8338             sincos(src0, dst.xy, dst.zw);
8339         }
8340 #endif
8341         0x43425844, 0xb47a22ec, 0xdb165106, 0xeee971d7, 0x8836fcc0, 0x00000001, 0x000000dc, 0x00000003,
8342         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8343         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8344         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000064, 0x00000050, 0x00000019,
8345         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8346         0x0700004d, 0x00102032, 0x00000000, 0x0000d000, 0x00208046, 0x00000000, 0x00000000, 0x0700004d,
8347         0x0000d000, 0x001020c2, 0x00000000, 0x00208406, 0x00000000, 0x00000000, 0x0100003e,
8348     };
8349     static struct named_shader ps_sincos = {"sincos", ps_sincos_code, sizeof(ps_sincos_code)};
8350     static const DWORD ps_indexable_temp_code[] =
8351     {
8352 #if 0
8353         float index;
8354 
8355         float4 main() : SV_Target
8356         {
8357             float4 colors[] =
8358             {
8359                 float4(1.0f, 0.0f, 0.0f, 1.0f),
8360                 float4(0.0f, 1.0f, 0.0f, 1.0f),
8361                 float4(0.0f, 0.0f, 1.0f, 1.0f),
8362             };
8363             return colors[index];
8364         }
8365 #endif
8366         0x43425844, 0x82c65bbb, 0x5b713473, 0xa16ebe60, 0xdcc329be, 0x00000001, 0x00000170, 0x00000003,
8367         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8368         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8369         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000f8, 0x00000050, 0x0000003e,
8370         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8371         0x02000068, 0x00000001, 0x04000069, 0x00000000, 0x00000003, 0x00000004, 0x09000036, 0x00203072,
8372         0x00000000, 0x00000000, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x09000036,
8373         0x00203072, 0x00000000, 0x00000001, 0x00004002, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
8374         0x09000036, 0x00203072, 0x00000000, 0x00000002, 0x00004002, 0x00000000, 0x00000000, 0x3f800000,
8375         0x00000000, 0x0600001c, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x07000036,
8376         0x00102072, 0x00000000, 0x04203246, 0x00000000, 0x0010000a, 0x00000000, 0x05000036, 0x00102082,
8377         0x00000000, 0x00004001, 0x3f800000, 0x0100003e,
8378     };
8379     static struct named_shader ps_indexable_temp = {"indexable_temp", ps_indexable_temp_code, sizeof(ps_indexable_temp_code)};
8380     static const DWORD ps_indexable_temp2_code[] =
8381     {
8382 #if 0
8383         float index;
8384 
8385         float4 main() : SV_Target
8386         {
8387             uint remap[] = {0, 1, 2, 2, 1, 0, 1, 1, 2, 2};
8388             float4 colors[] =
8389             {
8390                 float4(1.0f, 0.0f, 0.0f, 1.0f),
8391                 float4(0.0f, 1.0f, 0.0f, 1.0f),
8392                 float4(0.0f, 0.0f, 1.0f, 1.0f),
8393             };
8394             return colors[remap[index]];
8395         }
8396 #endif
8397         0x43425844, 0xcacc5b8f, 0x19bb905e, 0x6af8eae1, 0x80654684, 0x00000001, 0x0000028c, 0x00000003,
8398         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8399         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
8400         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000214, 0x00000050, 0x00000085,
8401         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8402         0x02000068, 0x00000001, 0x04000069, 0x00000000, 0x0000000a, 0x00000004, 0x04000069, 0x00000001,
8403         0x00000003, 0x00000004, 0x06000036, 0x00203012, 0x00000000, 0x00000000, 0x00004001, 0x00000000,
8404         0x06000036, 0x00203012, 0x00000000, 0x00000001, 0x00004001, 0x00000001, 0x06000036, 0x00203012,
8405         0x00000000, 0x00000002, 0x00004001, 0x00000002, 0x06000036, 0x00203012, 0x00000000, 0x00000003,
8406         0x00004001, 0x00000002, 0x06000036, 0x00203012, 0x00000000, 0x00000004, 0x00004001, 0x00000001,
8407         0x06000036, 0x00203012, 0x00000000, 0x00000005, 0x00004001, 0x00000000, 0x06000036, 0x00203012,
8408         0x00000000, 0x00000006, 0x00004001, 0x00000001, 0x06000036, 0x00203012, 0x00000000, 0x00000007,
8409         0x00004001, 0x00000001, 0x06000036, 0x00203012, 0x00000000, 0x00000008, 0x00004001, 0x00000002,
8410         0x06000036, 0x00203012, 0x00000000, 0x00000009, 0x00004001, 0x00000002, 0x09000036, 0x00203072,
8411         0x00000001, 0x00000000, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x09000036,
8412         0x00203072, 0x00000001, 0x00000001, 0x00004002, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
8413         0x09000036, 0x00203072, 0x00000001, 0x00000002, 0x00004002, 0x00000000, 0x00000000, 0x3f800000,
8414         0x00000000, 0x0600001c, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x07000036,
8415         0x00100012, 0x00000000, 0x0420300a, 0x00000000, 0x0010000a, 0x00000000, 0x07000036, 0x00102072,
8416         0x00000000, 0x04203246, 0x00000001, 0x0010000a, 0x00000000, 0x05000036, 0x00102082, 0x00000000,
8417         0x00004001, 0x3f800000, 0x0100003e,
8418     };
8419     static struct named_shader ps_indexable_temp2 = {"indexable_temp2", ps_indexable_temp2_code, sizeof(ps_indexable_temp2_code)};
8420     static const DWORD ps_bfi_code[] =
8421     {
8422 #if 0
8423         uint bits, offset, insert, base;
8424 
8425         uint4 main() : SV_Target
8426         {
8427             uint mask = ((1 << bits) - 1) << offset;
8428             return ((insert << offset) & mask) | (base & ~mask);
8429         }
8430 #endif
8431         0x43425844, 0xbe9af688, 0xf5caec6f, 0x63ed2522, 0x5f91f209, 0x00000001, 0x000000e0, 0x00000003,
8432         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8433         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8434         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000068, 0x00000050, 0x0000001a,
8435         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8436         0x0f00008c, 0x001020f2, 0x00000000, 0x00208006, 0x00000000, 0x00000000, 0x00208556, 0x00000000,
8437         0x00000000, 0x00208aa6, 0x00000000, 0x00000000, 0x00208ff6, 0x00000000, 0x00000000, 0x0100003e,
8438     };
8439     static struct named_shader ps_bfi = {"bfi", ps_bfi_code, sizeof(ps_bfi_code)};
8440     static const DWORD ps_ibfe_code[] =
8441     {
8442 #if 0
8443         ps_5_0
8444         dcl_globalFlags refactoringAllowed
8445         dcl_constantbuffer cb0[1], immediateIndexed
8446         dcl_output o0.xyzw
8447         ibfe o0.xyzw, cb0[0].xxxx, cb0[0].yyyy, cb0[0].zzzz
8448         ret
8449 #endif
8450         0x43425844, 0x4b2225f7, 0xd0860f66, 0xe38775bb, 0x6d23d1d2, 0x00000001, 0x000000d4, 0x00000003,
8451         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8452         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8453         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000005c, 0x00000050, 0x00000017,
8454         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8455         0x0c00008b, 0x001020f2, 0x00000000, 0x00208006, 0x00000000, 0x00000000, 0x00208556, 0x00000000,
8456         0x00000000, 0x00208aa6, 0x00000000, 0x00000000, 0x0100003e,
8457     };
8458     static struct named_shader ps_ibfe = {"ibfe", ps_ibfe_code, sizeof(ps_ibfe_code)};
8459     static const DWORD ps_ibfe2_code[] =
8460     {
8461 #if 0
8462         ps_5_0
8463         dcl_globalFlags refactoringAllowed
8464         dcl_constantbuffer cb0[1], immediateIndexed
8465         dcl_output o0.xyzw
8466         dcl_temps 1
8467         mov r0.xyzw, cb0[0].xyzw
8468         ibfe r0.xyzw, r0.xxxx, r0.yyyy, r0.zzzz
8469         mov o0.xyzw, r0.xyzw
8470         ret
8471 #endif
8472         0x43425844, 0x347a9c0e, 0x3eff39a4, 0x3dd41cc5, 0xff87ec8d, 0x00000001, 0x000000fc, 0x00000003,
8473         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8474         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8475         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000084, 0x00000050, 0x00000021,
8476         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8477         0x02000068, 0x00000001, 0x06000036, 0x001000f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000,
8478         0x0900008b, 0x001000f2, 0x00000000, 0x00100006, 0x00000000, 0x00100556, 0x00000000, 0x00100aa6,
8479         0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x0100003e,
8480     };
8481     static struct named_shader ps_ibfe2 = {"ibfe2", ps_ibfe2_code, sizeof(ps_ibfe2_code)};
8482     static const DWORD ps_ubfe_code[] =
8483     {
8484 #if 0
8485         uint u;
8486 
8487         uint4 main() : SV_Target
8488         {
8489             return uint4((u & 0xf0) >> 4, (u & 0x7fffff00) >> 8, (u & 0xfe) >> 1, (u & 0x7fffffff) >> 1);
8490         }
8491 #endif
8492         0x43425844, 0xc4ac0509, 0xaea83154, 0xf1fb3b80, 0x4c22e3cc, 0x00000001, 0x000000e4, 0x00000003,
8493         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8494         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8495         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000006c, 0x00000050, 0x0000001b,
8496         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8497         0x1000008a, 0x001020f2, 0x00000000, 0x00004002, 0x00000004, 0x00000017, 0x00000007, 0x0000001e,
8498         0x00004002, 0x00000004, 0x00000008, 0x00000001, 0x00000001, 0x00208006, 0x00000000, 0x00000000,
8499         0x0100003e,
8500     };
8501     static struct named_shader ps_ubfe = {"ubfe", ps_ubfe_code, sizeof(ps_ubfe_code)};
8502     static const DWORD ps_bfrev_code[] =
8503     {
8504 #if 0
8505         uint bits;
8506 
8507         uint4 main() : SV_Target
8508         {
8509             return uint4(reversebits(bits), reversebits(reversebits(bits)),
8510                     reversebits(bits & 0xFFFF), reversebits(bits >> 16));
8511         }
8512 #endif
8513         0x43425844, 0x73daef82, 0xe52befa3, 0x8504d5f0, 0xebdb321d, 0x00000001, 0x00000154, 0x00000003,
8514         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8515         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8516         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000dc, 0x00000050, 0x00000037,
8517         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8518         0x02000068, 0x00000001, 0x08000001, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000,
8519         0x00004001, 0x0000ffff, 0x0500008d, 0x00102042, 0x00000000, 0x0010000a, 0x00000000, 0x08000055,
8520         0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x00004001, 0x00000010, 0x0500008d,
8521         0x00102082, 0x00000000, 0x0010000a, 0x00000000, 0x0600008d, 0x00100012, 0x00000000, 0x0020800a,
8522         0x00000000, 0x00000000, 0x0500008d, 0x00102022, 0x00000000, 0x0010000a, 0x00000000, 0x05000036,
8523         0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e,
8524     };
8525     static struct named_shader ps_bfrev = {"bfrev", ps_bfrev_code, sizeof(ps_bfrev_code)};
8526     static const DWORD ps_bits_code[] =
8527     {
8528 #if 0
8529         uint u;
8530         int i;
8531 
8532         uint4 main() : SV_Target
8533         {
8534             return uint4(countbits(u), firstbitlow(u), firstbithigh(u), firstbithigh(i));
8535         }
8536 #endif
8537         0x43425844, 0x23fee911, 0x145287d1, 0xea904419, 0x8aa59a6a, 0x00000001, 0x000001b4, 0x00000003,
8538         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8539         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8540         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000013c, 0x00000050, 0x0000004f,
8541         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8542         0x02000068, 0x00000001, 0x06000089, 0x00100012, 0x00000000, 0x0020801a, 0x00000000, 0x00000000,
8543         0x07000020, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0xffffffff, 0x0800001e,
8544         0x00100012, 0x00000000, 0x00004001, 0x0000001f, 0x8010000a, 0x00000041, 0x00000000, 0x09000037,
8545         0x00102082, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0xffffffff, 0x0010000a, 0x00000000,
8546         0x06000087, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0800001e, 0x00100012,
8547         0x00000000, 0x00004001, 0x0000001f, 0x8010000a, 0x00000041, 0x00000000, 0x0a000037, 0x00102042,
8548         0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0xffffffff,
8549         0x06000086, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x06000088, 0x00102022,
8550         0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0100003e,
8551     };
8552     static struct named_shader ps_bits = {"bits", ps_bits_code, sizeof(ps_bits_code)};
8553     static const DWORD ps_ishr_code[] =
8554     {
8555 #if 0
8556         int4 src0;
8557         int4 src1;
8558 
8559         void main(out uint4 dst : SV_Target)
8560         {
8561             dst = src0 >> src1;
8562         }
8563 #endif
8564         0x43425844, 0x4551d737, 0xd3dcf723, 0xdf387a99, 0xb6d6b00b, 0x00000001, 0x000000c8, 0x00000003,
8565         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8566         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8567         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000050, 0x00000050, 0x00000014,
8568         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
8569         0x0900002a, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00208e46, 0x00000000,
8570         0x00000001, 0x0100003e,
8571     };
8572     static struct named_shader ps_ishr = {"ishr", ps_ishr_code, sizeof(ps_ishr_code)};
8573     static const DWORD ps_ushr_code[] =
8574     {
8575 #if 0
8576         uint4 src0;
8577         uint4 src1;
8578 
8579         void main(out uint4 dst : SV_Target)
8580         {
8581             dst = src0 >> src1;
8582         }
8583 #endif
8584         0x43425844, 0x00f49f17, 0xe7933d92, 0xf527d4e6, 0x1fe1c216, 0x00000001, 0x000000c8, 0x00000003,
8585         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8586         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8587         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000050, 0x00000050, 0x00000014,
8588         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
8589         0x09000055, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00208e46, 0x00000000,
8590         0x00000001, 0x0100003e,
8591     };
8592     static struct named_shader ps_ushr = {"ushr", ps_ushr_code, sizeof(ps_ushr_code)};
8593     static const DWORD ps_ishl_code[] =
8594     {
8595 #if 0
8596         uint4 src0;
8597         uint4 src1;
8598 
8599         void main(out uint4 dst : SV_Target)
8600         {
8601             dst = src0 << src1;
8602         }
8603 #endif
8604         0x43425844, 0xc88f5e4d, 0x64e1e5c6, 0x70e7173e, 0x960d6691, 0x00000001, 0x000000c8, 0x00000003,
8605         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8606         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8607         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000050, 0x00000050, 0x00000014,
8608         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
8609         0x09000029, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00208e46, 0x00000000,
8610         0x00000001, 0x0100003e,
8611     };
8612     static struct named_shader ps_ishl = {"ishl", ps_ishl_code, sizeof(ps_ishl_code)};
8613     static const DWORD ps_ishl_const_code[] =
8614     {
8615 #if 0
8616         uint4 src;
8617 
8618         void main(out uint4 dst : SV_Target)
8619         {
8620             dst = src << 2;
8621         }
8622 #endif
8623         0x43425844, 0x5b749bf4, 0xe24de3dc, 0xbbd75bc9, 0xc6fc9eca, 0x00000001, 0x000000c0, 0x00000003,
8624         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8625         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8626         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000048, 0x00000040, 0x00000012,
8627         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x08000029,
8628         0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00004001, 0x00000002, 0x0100003e,
8629     };
8630     static struct named_shader ps_ishl_const = {"ishl_const", ps_ishl_const_code, sizeof(ps_ishl_const_code)};
8631     static const DWORD ps_not_code[] =
8632     {
8633 #if 0
8634         uint2 bits;
8635 
8636         uint4 main() : SV_Target
8637         {
8638             return uint4(~bits.x, ~(bits.x ^ ~0u), ~bits.y, ~(bits.y ^ ~0u));
8639         }
8640 #endif
8641         0x43425844, 0xaed0fd26, 0xf719a878, 0xc832efd6, 0xba03c264, 0x00000001, 0x00000100, 0x00000003,
8642         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8643         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8644         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000088, 0x00000040, 0x00000022,
8645         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
8646         0x00000001, 0x0b000057, 0x00100032, 0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x00004002,
8647         0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x0500003b, 0x001020a2, 0x00000000, 0x00100406,
8648         0x00000000, 0x0600003b, 0x00102052, 0x00000000, 0x00208106, 0x00000000, 0x00000000, 0x0100003e,
8649     };
8650     static struct named_shader ps_not = {"not", ps_not_code, sizeof(ps_not_code)};
8651     static const DWORD ps_icmp_code[] =
8652     {
8653 #if 0
8654         int2 src;
8655 
8656         void main(out uint4 dst : SV_Target)
8657         {
8658             dst.x = src.x == src.y ? ~0u : 0;
8659             dst.y = src.x >= src.y ? ~0u : 0;
8660             dst.z = src.x < src.y  ? ~0u : 0;
8661             dst.w = src.x != src.y ? ~0u : 0;
8662         }
8663 #endif
8664         0x43425844, 0xa39748f0, 0x39d5c9e4, 0xdf073d48, 0x7946c5c4, 0x00000001, 0x00000134, 0x00000003,
8665         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8666         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8667         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000bc, 0x00000050, 0x0000002f,
8668         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8669         0x09000020, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0020801a, 0x00000000,
8670         0x00000000, 0x09000021, 0x00102022, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0020801a,
8671         0x00000000, 0x00000000, 0x09000022, 0x00102042, 0x00000000, 0x0020800a, 0x00000000, 0x00000000,
8672         0x0020801a, 0x00000000, 0x00000000, 0x09000027, 0x00102082, 0x00000000, 0x0020800a, 0x00000000,
8673         0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x0100003e,
8674     };
8675     static struct named_shader ps_icmp = {"icmp", ps_icmp_code, sizeof(ps_icmp_code)};
8676     static const DWORD ps_ucmp_code[] =
8677     {
8678 #if 0
8679         uint2 src;
8680 
8681         void main(out uint4 dst : SV_Target)
8682         {
8683             dst = 0;
8684             dst.x = src.x >= src.y ? ~0u : 0;
8685             dst.y = src.x < src.y  ? ~0u : 0;
8686         }
8687 #endif
8688         0x43425844, 0xe083954f, 0xb55bf642, 0xeb2fa36c, 0x60ee1782, 0x00000001, 0x0000010c, 0x00000003,
8689         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8690         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8691         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000094, 0x00000050, 0x00000025,
8692         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8693         0x09000050, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0020801a, 0x00000000,
8694         0x00000000, 0x0900004f, 0x00102022, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0020801a,
8695         0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
8696         0x00000000, 0x00000000, 0x0100003e,
8697     };
8698     static struct named_shader ps_ucmp = {"ucmp", ps_ucmp_code, sizeof(ps_ucmp_code)};
8699     static const DWORD ps_umin_umax_code[] =
8700     {
8701 #if 0
8702         uint2 src;
8703 
8704         void main(out uint4 dst : SV_Target)
8705         {
8706             dst.x = min(src.x, src.y);
8707             dst.y = max(src.x, src.y);
8708             dst.zw = 0;
8709         }
8710 #endif
8711         0x43425844, 0xe705f812, 0xa515c8df, 0xb82066d9, 0xb05c8ad3, 0x00000001, 0x0000010c, 0x00000003,
8712         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8713         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8714         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000094, 0x00000050, 0x00000025,
8715         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8716         0x09000054, 0x00102012, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x0020800a, 0x00000000,
8717         0x00000000, 0x09000053, 0x00102022, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x0020800a,
8718         0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
8719         0x00000000, 0x00000000, 0x0100003e,
8720     };
8721     static struct named_shader ps_umin_umax = {"umin_umax", ps_umin_umax_code, sizeof(ps_umin_umax_code)};
8722     static const DWORD ps_f16tof32_code[] =
8723     {
8724 #if 0
8725         uint4 hf;
8726 
8727         uint4 main() : SV_Target
8728         {
8729             return f16tof32(hf);
8730         }
8731 #endif
8732         0x43425844, 0xc1816e6e, 0x27562d96, 0x56980fa2, 0x421e6640, 0x00000001, 0x000000d8, 0x00000003,
8733         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8734         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8735         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000060, 0x00000050, 0x00000018,
8736         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8737         0x02000068, 0x00000001, 0x06000083, 0x001000f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000,
8738         0x0500001c, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x0100003e,
8739     };
8740     static struct named_shader ps_f16tof32 = {"f16tof32", ps_f16tof32_code, sizeof(ps_f16tof32_code)};
8741     static const DWORD ps_f16tof32_2_code[] =
8742     {
8743 #if 0
8744         ps_5_0
8745         dcl_globalFlags refactoringAllowed
8746         dcl_constantbuffer cb0[1], immediateIndexed
8747         dcl_output o0.xyzw
8748         dcl_temps 1
8749         mov r0.xyzw, cb0[0].xyzw
8750         f16tof32 r0.xyzw, r0.wzyx
8751         ftou o0.xyzw, r0.xyzw
8752         ret
8753 #endif
8754         0x43425844, 0x38472f03, 0x2c49b7dd, 0xc2d76bbf, 0xfc093e1d, 0x00000001, 0x000000ec, 0x00000003,
8755         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8756         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8757         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000074, 0x00000050, 0x0000001d,
8758         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8759         0x02000068, 0x00000001, 0x06000036, 0x001000f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000,
8760         0x05000083, 0x001000f2, 0x00000000, 0x001001b6, 0x00000000, 0x0500001c, 0x001020f2, 0x00000000,
8761         0x00100e46, 0x00000000, 0x0100003e,
8762     };
8763     static struct named_shader ps_f16tof32_2 = {"f16tof32_2", ps_f16tof32_2_code, sizeof(ps_f16tof32_2_code)};
8764     static const DWORD ps_f32tof16_code[] =
8765     {
8766 #if 0
8767         float4 f;
8768 
8769         uint4 main() : SV_Target
8770         {
8771             return f32tof16(f);
8772         }
8773 #endif
8774         0x43425844, 0x523a765c, 0x1a5be3a9, 0xaed69c80, 0xd26fe296, 0x00000001, 0x000000bc, 0x00000003,
8775         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8776         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8777         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000044, 0x00000050, 0x00000011,
8778         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8779         0x06000082, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e,
8780     };
8781     static struct named_shader ps_f32tof16 = {"f32tof16", ps_f32tof16_code, sizeof(ps_f32tof16_code)};
8782     static const DWORD ps_f32tof16_2_code[] =
8783     {
8784 #if 0
8785         ps_5_0
8786         dcl_globalFlags refactoringAllowed
8787         dcl_constantbuffer cb0[1], immediateIndexed
8788         dcl_output o0.xyzw
8789         dcl_temps 1
8790         mov r0.xyzw, cb0[0].xyzw
8791         f32tof16 r0.xyzw, r0.wzyx
8792         mov o0.xyzw, r0.xyzw
8793         ret
8794 #endif
8795         0x43425844, 0x607c82d2, 0x940cc7c2, 0xe9de23c6, 0x696beb90, 0x00000001, 0x000000ec, 0x00000003,
8796         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8797         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8798         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000074, 0x00000050, 0x0000001d,
8799         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8800         0x02000068, 0x00000001, 0x06000036, 0x001000f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000,
8801         0x05000082, 0x001000f2, 0x00000000, 0x001001b6, 0x00000000, 0x05000036, 0x001020f2, 0x00000000,
8802         0x00100e46, 0x00000000, 0x0100003e,
8803     };
8804     static struct named_shader ps_f32tof16_2 = {"f32tof16_2", ps_f32tof16_2_code, sizeof(ps_f32tof16_2_code)};
8805     static const DWORD ps_imad_code[] =
8806     {
8807 #if 0
8808         int4 src0;
8809         int4 src1;
8810         int4 src2;
8811 
8812         void main(out uint4 dst : SV_Target)
8813         {
8814             dst.xy = src0.xy * src1.xy + src2.xy;
8815             dst.zw = src0.zw * src1.zw - src2.zw;
8816         }
8817 #endif
8818         0x43425844, 0xb6a7735a, 0xc891e560, 0x6df8f267, 0x2753395c, 0x00000001, 0x00000108, 0x00000003,
8819         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8820         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8821         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000090, 0x00000050, 0x00000024,
8822         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000003, 0x03000065, 0x001020f2, 0x00000000,
8823         0x0c000023, 0x00102032, 0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x00208046, 0x00000000,
8824         0x00000001, 0x00208046, 0x00000000, 0x00000002, 0x0d000023, 0x001020c2, 0x00000000, 0x00208ea6,
8825         0x00000000, 0x00000000, 0x00208ea6, 0x00000000, 0x00000001, 0x80208ea6, 0x00000041, 0x00000000,
8826         0x00000002, 0x0100003e,
8827     };
8828     static struct named_shader ps_imad = {"imad", ps_imad_code, sizeof(ps_imad_code)};
8829     static const DWORD ps_imul_code[] =
8830     {
8831 #if 0
8832         uint4 src0;
8833         uint4 src1;
8834 
8835         void main(out uint4 dst : SV_Target)
8836         {
8837             dst = 0;
8838             dst.x = src0.x * src1.x;
8839         }
8840 #endif
8841         0x43425844, 0x55ebfe14, 0xc9834c14, 0x5f89388a, 0x523be7e0, 0x00000001, 0x000000ec, 0x00000003,
8842         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8843         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8844         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000074, 0x00000050, 0x0000001d,
8845         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
8846         0x0a000026, 0x0000d000, 0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0020800a,
8847         0x00000000, 0x00000001, 0x08000036, 0x001020e2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
8848         0x00000000, 0x00000000, 0x0100003e,
8849     };
8850     static struct named_shader ps_imul = {"imul", ps_imul_code, sizeof(ps_imul_code)};
8851     static const DWORD ps_udiv_code[] =
8852     {
8853 #if 0
8854         uint4 src0;
8855         uint4 src1;
8856 
8857         void main(out uint4 dst : SV_Target)
8858         {
8859             dst = 0;
8860             dst.x = src0.x / src1.x;
8861             dst.y = src0.x % src1.x;
8862         }
8863 #endif
8864         0x43425844, 0x007d5f29, 0x042f2e56, 0x212eddf2, 0xc98cca76, 0x00000001, 0x00000120, 0x00000003,
8865         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8866         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8867         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000a8, 0x00000050, 0x0000002a,
8868         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
8869         0x02000068, 0x00000002, 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
8870         0x00000000, 0x00000000, 0x0b00004e, 0x00100012, 0x00000000, 0x00100012, 0x00000001, 0x0020800a,
8871         0x00000000, 0x00000000, 0x0020800a, 0x00000000, 0x00000001, 0x05000036, 0x00102012, 0x00000000,
8872         0x0010000a, 0x00000000, 0x05000036, 0x00102022, 0x00000000, 0x0010000a, 0x00000001, 0x0100003e,
8873     };
8874     static struct named_shader ps_udiv = {"udiv", ps_udiv_code, sizeof(ps_udiv_code)};
8875     static const DWORD ps_nested_switch_code[] =
8876     {
8877 #if 0
8878         uint4 src0;
8879         uint4 src1;
8880 
8881         uint4 main() : SV_Target
8882         {
8883             uint4 dst = 0;
8884 
8885             switch (src0.x)
8886             {
8887                 case ~0u:
8888                     dst.x = 1;
8889                     break;
8890                 case 0:
8891                 case 1:
8892                 case 2:
8893                     if (src1.x)
8894                         break;
8895                     dst.x = 2;
8896                     break;
8897                 case 3:
8898                     break;
8899                 case 4:
8900                     if (src1.x)
8901                     {
8902                         switch (src0.y)
8903                         {
8904                             case 0:
8905                             case 1:
8906                             case 2:
8907                             case 3:
8908                                 if (src0.z)
8909                                     dst += src0.z * (uint4)2;
8910                                 else if (src0.w)
8911                                     return (uint4)255;
8912                                 else
8913                                     dst.zw = 1;
8914                                 break;
8915                             default:
8916                                 dst = 1;
8917                                 break;
8918                         }
8919                         break;
8920                     }
8921                     else
8922                     {
8923                         dst = 128;
8924                         break;
8925                     }
8926             }
8927 
8928             return dst;
8929         }
8930 #endif
8931         0x43425844, 0x46d465cb, 0x5d7ed52f, 0x3573b153, 0x1691c479, 0x00000001, 0x00000334, 0x00000003,
8932         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8933         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8934         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000002bc, 0x00000050, 0x000000af,
8935         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
8936         0x02000068, 0x00000001, 0x0400004c, 0x0020800a, 0x00000000, 0x00000000, 0x03000006, 0x00004001,
8937         0xffffffff, 0x08000036, 0x001000f2, 0x00000000, 0x00004002, 0x00000001, 0x00000000, 0x00000000,
8938         0x00000000, 0x01000002, 0x03000006, 0x00004001, 0x00000000, 0x03000006, 0x00004001, 0x00000001,
8939         0x03000006, 0x00004001, 0x00000002, 0x0404001f, 0x0020800a, 0x00000000, 0x00000001, 0x08000036,
8940         0x001000f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01000002,
8941         0x01000015, 0x08000036, 0x001000f2, 0x00000000, 0x00004002, 0x00000002, 0x00000000, 0x00000000,
8942         0x00000000, 0x01000002, 0x03000006, 0x00004001, 0x00000003, 0x08000036, 0x001000f2, 0x00000000,
8943         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01000002, 0x03000006, 0x00004001,
8944         0x00000004, 0x0404001f, 0x0020800a, 0x00000000, 0x00000001, 0x0400004c, 0x0020801a, 0x00000000,
8945         0x00000000, 0x03000006, 0x00004001, 0x00000000, 0x03000006, 0x00004001, 0x00000001, 0x03000006,
8946         0x00004001, 0x00000002, 0x03000006, 0x00004001, 0x00000003, 0x0404001f, 0x0020802a, 0x00000000,
8947         0x00000000, 0x0b000029, 0x001000f2, 0x00000000, 0x00208aa6, 0x00000000, 0x00000000, 0x00004002,
8948         0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x01000012, 0x0404001f, 0x0020803a, 0x00000000,
8949         0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x000000ff, 0x000000ff, 0x000000ff,
8950         0x000000ff, 0x0100003e, 0x01000015, 0x08000036, 0x001000f2, 0x00000000, 0x00004002, 0x00000000,
8951         0x00000000, 0x00000001, 0x00000001, 0x01000015, 0x01000002, 0x0100000a, 0x08000036, 0x001000f2,
8952         0x00000000, 0x00004002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x01000002, 0x01000017,
8953         0x01000002, 0x01000012, 0x08000036, 0x001000f2, 0x00000000, 0x00004002, 0x00000080, 0x00000080,
8954         0x00000080, 0x00000080, 0x01000002, 0x01000015, 0x0100000a, 0x08000036, 0x001000f2, 0x00000000,
8955         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01000002, 0x01000017, 0x05000036,
8956         0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x0100003e,
8957     };
8958     static struct named_shader ps_nested_switch = {"nested_switch", ps_nested_switch_code, sizeof(ps_nested_switch_code)};
8959     static const DWORD ps_switch_no_default_code[] =
8960     {
8961 #if 0
8962         ps_5_0
8963         dcl_globalFlags refactoringAllowed
8964         dcl_constantbuffer CB0[1], immediateIndexed
8965         dcl_output o0.xyzw
8966         switch cb0[0].x
8967             case l(0)
8968             mov o0.xyzw, l(1,1,1,1)
8969             ret
8970             case l(3)
8971             mov o0.xyzw, l(2,2,2,2)
8972             ret
8973         endswitch
8974         nop
8975         nop
8976         mov o0.xyzw, l(3,3,3,3)
8977         ret
8978 #endif
8979         0x43425844, 0x97459226, 0x57ed7614, 0xcda58342, 0xbdf6a9dd, 0x00000001, 0x00000140, 0x00000003,
8980         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
8981         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
8982         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000c8, 0x00000050, 0x00000032,
8983         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
8984         0x0400004c, 0x0020800a, 0x00000000, 0x00000000, 0x03000006, 0x00004001, 0x00000000, 0x08000036,
8985         0x001020f2, 0x00000000, 0x00004002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x0100003e,
8986         0x03000006, 0x00004001, 0x00000003, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000002,
8987         0x00000002, 0x00000002, 0x00000002, 0x0100003e, 0x01000017, 0x0100003a, 0x0100003a, 0x08000036,
8988         0x001020f2, 0x00000000, 0x00004002, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x0100003e,
8989     };
8990     static const struct named_shader ps_switch_no_default
8991             = {"switch_no_default", ps_switch_no_default_code, sizeof(ps_switch_no_default_code)};
8992     static const DWORD ps_movc_code[] =
8993     {
8994 #if 0
8995         ps_5_0
8996         dcl_globalFlags refactoringAllowed
8997         dcl_constantbuffer cb0[3], immediateIndexed
8998         dcl_output o0.xyzw
8999         dcl_temps 1
9000         mov r0.xyzw, cb0[0].xyzw
9001         movc r0.xyzw, r0.xyzw, cb0[1].xyzw, cb0[2].xyzw
9002         mov o0.xyzw, r0.xyzw
9003         ret
9004 #endif
9005         0x43425844, 0x59a5be58, 0x260c36c0, 0x7eadcff2, 0x947f4e9d, 0x00000001, 0x00000104, 0x00000003,
9006         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
9007         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
9008         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000008c, 0x00000050, 0x00000023,
9009         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000003, 0x03000065, 0x001020f2, 0x00000000,
9010         0x02000068, 0x00000001, 0x06000036, 0x001000f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000,
9011         0x0b000037, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000001,
9012         0x00208e46, 0x00000000, 0x00000002, 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
9013         0x0100003e,
9014     };
9015     static struct named_shader ps_movc = {"movc", ps_movc_code, sizeof(ps_movc_code)};
9016     static const DWORD ps_swapc0_code[] =
9017     {
9018 #if 0
9019         ps_5_0
9020         dcl_globalFlags refactoringAllowed
9021         dcl_constantbuffer cb0[3], immediateIndexed
9022         dcl_output o0.xyzw
9023         dcl_temps 2
9024         swapc r0.xyzw, r1.xyzw, cb0[0].xyzw, cb0[1].xyzw, cb0[2].xyzw
9025         mov o0.xyzw, r0.xyzw
9026         ret
9027 #endif
9028         0x43425844, 0x9e089246, 0x9f8b5cbe, 0xbac66faf, 0xaef23488, 0x00000001, 0x000000f8, 0x00000003,
9029         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
9030         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
9031         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000080, 0x00000050, 0x00000020,
9032         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000003, 0x03000065, 0x001020f2, 0x00000000,
9033         0x02000068, 0x00000002, 0x0e00008e, 0x001000f2, 0x00000000, 0x001000f2, 0x00000001, 0x00208e46,
9034         0x00000000, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x00208e46, 0x00000000, 0x00000002,
9035         0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x0100003e,
9036     };
9037     static struct named_shader ps_swapc0 = {"swapc0", ps_swapc0_code, sizeof(ps_swapc0_code)};
9038     static const DWORD ps_swapc1_code[] =
9039     {
9040 #if 0
9041         ps_5_0
9042         dcl_globalFlags refactoringAllowed
9043         dcl_constantbuffer cb0[3], immediateIndexed
9044         dcl_output o0.xyzw
9045         dcl_temps 2
9046         swapc r0.xyzw, r1.xyzw, cb0[0].xyzw, cb0[1].xyzw, cb0[2].xyzw
9047         mov o0.xyzw, r1.xyzw
9048         ret
9049 #endif
9050         0x43425844, 0xf2daed61, 0xede211f7, 0x7300dbea, 0x573ed49f, 0x00000001, 0x000000f8, 0x00000003,
9051         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
9052         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
9053         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000080, 0x00000050, 0x00000020,
9054         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000003, 0x03000065, 0x001020f2, 0x00000000,
9055         0x02000068, 0x00000002, 0x0e00008e, 0x001000f2, 0x00000000, 0x001000f2, 0x00000001, 0x00208e46,
9056         0x00000000, 0x00000000, 0x00208e46, 0x00000000, 0x00000001, 0x00208e46, 0x00000000, 0x00000002,
9057         0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000001, 0x0100003e,
9058     };
9059     static struct named_shader ps_swapc1 = {"swapc1", ps_swapc1_code, sizeof(ps_swapc1_code)};
9060     static const DWORD ps_swapc2_code[] =
9061     {
9062 #if 0
9063         ps_5_0
9064         dcl_globalFlags refactoringAllowed
9065         dcl_constantbuffer cb0[3], immediateIndexed
9066         dcl_output o0.xyzw
9067         dcl_temps 2
9068         mov r0.xyzw, cb0[1].xyzw
9069         mov r1.xyzw, cb0[2].xyzw
9070         swapc r0.xyzw, r1.xyzw, cb0[0].xyzw, r0.xyzw, r1.xyzw
9071         mov o0.xyzw, r0.xyzw
9072         ret
9073 #endif
9074         0x43425844, 0x230fcb22, 0x70d99148, 0x65814d89, 0x97473498, 0x00000001, 0x00000120, 0x00000003,
9075         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
9076         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
9077         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000a8, 0x00000050, 0x0000002a,
9078         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000003, 0x03000065, 0x001020f2, 0x00000000,
9079         0x02000068, 0x00000002, 0x06000036, 0x001000f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000001,
9080         0x06000036, 0x001000f2, 0x00000001, 0x00208e46, 0x00000000, 0x00000002, 0x0c00008e, 0x001000f2,
9081         0x00000000, 0x001000f2, 0x00000001, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000,
9082         0x00100e46, 0x00000001, 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x0100003e,
9083     };
9084     static struct named_shader ps_swapc2 = {"swapc2", ps_swapc2_code, sizeof(ps_swapc2_code)};
9085     static const DWORD ps_swapc3_code[] =
9086     {
9087 #if 0
9088         ps_5_0
9089         dcl_globalFlags refactoringAllowed
9090         dcl_constantbuffer cb0[3], immediateIndexed
9091         dcl_output o0.xyzw
9092         dcl_temps 2
9093         mov r0.xyzw, cb0[1].xyzw
9094         mov r1.xyzw, cb0[2].xyzw
9095         swapc r0.xyzw, r1.xyzw, cb0[0].xyzw, r0.xyzw, r1.xyzw
9096         mov o0.xyzw, r1.xyzw
9097         ret
9098 #endif
9099         0x43425844, 0xce595d62, 0x98305541, 0xb04e74c8, 0xfc010f3a, 0x00000001, 0x00000120, 0x00000003,
9100         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
9101         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
9102         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000a8, 0x00000050, 0x0000002a,
9103         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000003, 0x03000065, 0x001020f2, 0x00000000,
9104         0x02000068, 0x00000002, 0x06000036, 0x001000f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000001,
9105         0x06000036, 0x001000f2, 0x00000001, 0x00208e46, 0x00000000, 0x00000002, 0x0c00008e, 0x001000f2,
9106         0x00000000, 0x001000f2, 0x00000001, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000,
9107         0x00100e46, 0x00000001, 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000001, 0x0100003e,
9108     };
9109     static struct named_shader ps_swapc3 = {"swapc3", ps_swapc3_code, sizeof(ps_swapc3_code)};
9110     static const DWORD ps_swapc4_code[] =
9111     {
9112 #if 0
9113         ps_5_0
9114         dcl_globalFlags refactoringAllowed
9115         dcl_constantbuffer cb0[3], immediateIndexed
9116         dcl_output o0.xyzw
9117         dcl_temps 2
9118         mov r0.xyzw, cb0[0].xyzw
9119         swapc r0.xyzw, r1.xyzw, r0.xyzw, cb0[1].xyzw, cb0[2].xyzw
9120         mov o0.xyzw, r0.xyzw
9121         ret
9122 #endif
9123         0x43425844, 0x72067c48, 0xb53572a0, 0x9dd9e0fd, 0x903e37e3, 0x00000001, 0x0000010c, 0x00000003,
9124         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
9125         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
9126         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000094, 0x00000050, 0x00000025,
9127         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000003, 0x03000065, 0x001020f2, 0x00000000,
9128         0x02000068, 0x00000002, 0x06000036, 0x001000f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000,
9129         0x0d00008e, 0x001000f2, 0x00000000, 0x001000f2, 0x00000001, 0x00100e46, 0x00000000, 0x00208e46,
9130         0x00000000, 0x00000001, 0x00208e46, 0x00000000, 0x00000002, 0x05000036, 0x001020f2, 0x00000000,
9131         0x00100e46, 0x00000000, 0x0100003e,
9132     };
9133     static struct named_shader ps_swapc4 = {"swapc4", ps_swapc4_code, sizeof(ps_swapc4_code)};
9134     static const DWORD ps_swapc5_code[] =
9135     {
9136 #if 0
9137         ps_5_0
9138         dcl_globalFlags refactoringAllowed
9139         dcl_constantbuffer cb0[3], immediateIndexed
9140         dcl_output o0.xyzw
9141         dcl_temps 2
9142         mov r1.xyzw, cb0[0].xyzw
9143         swapc r0.xyzw, r1.xyzw, r1.xyzw, cb0[1].xyzw, cb0[2].xyzw
9144         mov o0.xyzw, r1.xyzw
9145         ret
9146 #endif
9147         0x43425844, 0x7078fb08, 0xdd24cd44, 0x469d3258, 0x9e33a0bc, 0x00000001, 0x0000010c, 0x00000003,
9148         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
9149         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
9150         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000094, 0x00000050, 0x00000025,
9151         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000003, 0x03000065, 0x001020f2, 0x00000000,
9152         0x02000068, 0x00000002, 0x06000036, 0x001000f2, 0x00000001, 0x00208e46, 0x00000000, 0x00000000,
9153         0x0d00008e, 0x001000f2, 0x00000000, 0x001000f2, 0x00000001, 0x00100e46, 0x00000001, 0x00208e46,
9154         0x00000000, 0x00000001, 0x00208e46, 0x00000000, 0x00000002, 0x05000036, 0x001020f2, 0x00000000,
9155         0x00100e46, 0x00000001, 0x0100003e,
9156     };
9157     static struct named_shader ps_swapc5 = {"swapc5", ps_swapc5_code, sizeof(ps_swapc5_code)};
9158     static const struct
9159     {
9160         const struct named_shader *ps;
9161         struct
9162         {
9163             struct vec4 src0;
9164             struct vec4 src1;
9165             struct vec4 src2;
9166         } input;
9167         union
9168         {
9169             struct vec4 f;
9170             struct uvec4 u;
9171             struct ivec4 i;
9172         } output;
9173         bool skip_on_warp;
9174         bool is_mesa_bug;
9175     }
9176     tests[] =
9177     {
9178         {&ps_div, {{ 2.0f}, { 4.0f}}, {{     0.5f}}},
9179         {&ps_div, {{ 2.0f}, {-4.0f}}, {{    -0.5f}}},
9180         {&ps_div, {{-2.0f}, { 4.0f}}, {{    -0.5f}}},
9181         {&ps_div, {{-2.0f}, {-4.0f}}, {{     0.5f}}},
9182         {&ps_div, {{ 0.0f}, { 1.0f}}, {{     0.0f}}},
9183         {&ps_div, {{ 0.0f}, {-1.0f}}, {{    -0.0f}}},
9184         {&ps_div, {{ 1.0f}, { 0.0f}}, {{ INFINITY}}},
9185         {&ps_div, {{ 1.0f}, {-0.0f}}, {{-INFINITY}}},
9186         {&ps_div, {{-1.0f}, { 0.0f}}, {{-INFINITY}}},
9187         {&ps_div, {{-1.0f}, {-0.0f}}, {{ INFINITY}}},
9188 
9189         {&ps_dot2, {{1.0f, 1.0f}, {1.0f, 1.0f}}, {{2.0f}}},
9190         {&ps_dot2, {{1.0f, 1.0f}, {2.0f, 3.0f}}, {{5.0f}}},
9191 
9192         {&ps_dot3, {{1.0f, 2.0f, 3.0f, 4.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, {{6.0f, 6.0f, 6.0f, 6.0f}}},
9193         {&ps_dot3, {{1.0f, 2.0f, 3.0f}, {3.0f, 1.0f, 2.0f}}, {{11.0f, 11.0f, 11.0f, 11.0f}}},
9194 
9195         {&ps_eq, {{0.0f}, {0.0f}}, {.u = {0xffffffff}}},
9196         {&ps_eq, {{1.0f}, {0.0f}}, {.u = {0x00000000}}},
9197         {&ps_eq, {{0.0f}, {1.0f}}, {.u = {0x00000000}}},
9198         {&ps_eq, {{1.0f}, {1.0f}}, {.u = {0xffffffff}}},
9199         {&ps_eq, {{0.0f},  {NAN}}, {.u = {0x00000000}}},
9200         {&ps_eq, {{1.0f},  {NAN}}, {.u = {0x00000000}}},
9201         {&ps_eq, { {NAN},  {NAN}}, {.u = {0x00000000}}},
9202 
9203         {&ps_ne, {{0.0f}, {0.0f}}, {.u = {0x00000000}}},
9204         {&ps_ne, {{1.0f}, {0.0f}}, {.u = {0xffffffff}}},
9205         {&ps_ne, {{0.0f}, {1.0f}}, {.u = {0xffffffff}}},
9206         {&ps_ne, {{1.0f}, {1.0f}}, {.u = {0x00000000}}},
9207         {&ps_ne, {{0.0f},  {NAN}}, {.u = {0xffffffff}}},
9208         {&ps_ne, {{1.0f},  {NAN}}, {.u = {0xffffffff}}},
9209         {&ps_ne, { {NAN},  {NAN}}, {.u = {0xffffffff}}},
9210 
9211         {&ps_if, {{0.0f}}, {{1.0f, 0.0f, 0.0f, 1.0f}}},
9212         {&ps_if, {{1.0f}}, {{0.0f, 1.0f, 0.0f, 1.0f}}},
9213 
9214         /* FIXME: Ordered/unordered comparisons are broken on Mesa. */
9215         {&ps_if_return, {{0.0f, 0.0f, 0.0f, 0.0f}}, {{0.0f, 0.0f, 0.0f, 0.0f}}},
9216         {&ps_if_return, {{ NAN, 0.0f, 0.0f, 0.0f}}, {{1.0f, 0.0f, 0.0f, 0.0f}}, false, true},
9217         {&ps_if_return, {{3.0f, 0.0f, 0.0f, 0.0f}}, {{0.0f, 0.0f, 0.0f, 0.0f}}},
9218         {&ps_if_return, {{4.0f, 0.0f, 0.0f, 0.0f}}, {{1.0f, 0.0f, 0.0f, 0.0f}}},
9219         {&ps_if_return, {{4.0f,  NAN, 0.0f, 0.0f}}, {{1.0f, 1.0f, 1.0f, 0.0f}}, false, true},
9220         {&ps_if_return, {{4.0f, 3.0f, 0.0f, 0.0f}}, {{1.0f, 0.0f, 0.0f, 0.0f}}},
9221         {&ps_if_return, {{4.0f, 4.0f, 0.0f, 0.0f}}, {{1.0f, 1.0f, 1.0f, 0.0f}}},
9222         {&ps_if_return, {{4.0f, 4.0f,  NAN, 0.0f}}, {{1.0f, 1.0f, 1.0f, 0.0f}}, false, true},
9223         {&ps_if_return, {{4.0f, 4.0f, 3.0f, 0.0f}}, {{1.0f, 1.0f, 1.0f, 0.0f}}},
9224         {&ps_if_return, {{4.0f, 4.0f, 4.0f, 0.0f}}, {{1.0f, 1.0f, 0.0f, 0.0f}}},
9225         {&ps_if_return, {{4.0f, 4.0f, 5.0f, 0.0f}}, {{1.0f, 1.0f, 0.0f, 0.0f}}},
9226         {&ps_if_return, {{4.0f, 4.0f, 0.0f,  NAN}}, {{1.0f, 1.0f, 1.0f, 1.0f}}, false, true},
9227         {&ps_if_return, {{4.0f, 4.0f, 0.0f, 1.0f}}, {{1.0f, 1.0f, 1.0f, 0.0f}}},
9228         {&ps_if_return, {{4.0f, 4.0f, 0.0f, 2.0f}}, {{1.0f, 1.0f, 1.0f, 0.0f}}},
9229         {&ps_if_return, {{4.0f, 4.0f, 0.0f, 3.0f}}, {{1.0f, 1.0f, 1.0f, 0.0f}}},
9230         {&ps_if_return, {{4.0f, 4.0f, 0.0f, 4.0f}}, {{1.0f, 1.0f, 1.0f, 0.0f}}},
9231         {&ps_if_return, {{4.0f, 4.0f, 0.0f, 5.0f}}, {{1.0f, 1.0f, 1.0f, 1.0f}}},
9232         {&ps_if_return, {{5.0f, 4.0f, 0.0f, 5.0f}}, {{1.0f, 1.0f, 1.0f, 0.0f}}},
9233         {&ps_if_return, {{ NAN,  NAN,  NAN,  NAN}}, {{1.0f, 1.0f, 1.0f, 1.0f}}, false, true},
9234 
9235         {&ps_nested_if, {{0.0f, 0.0f, 0.0f}}, {{0.0f, 0.0f, 0.0f, 1.0f}}},
9236         {&ps_nested_if, {{0.0f, 0.0f, 1.0f}}, {{1.0f, 0.0f, 0.0f, 1.0f}}},
9237         {&ps_nested_if, {{1.0f, 0.0f, 1.0f}}, {{0.0f, 0.0f, 1.0f, 1.0f}}},
9238         {&ps_nested_if, {{1.0f, 1.0f, 1.0f}}, {{0.0f, 1.0f, 0.0f, 1.0f}}},
9239 
9240         {&ps_loop_break, {{0.0f, 0.0f}}, {{0.0f}}},
9241         {&ps_loop_break, {{1.0f, 0.0f}}, {{1.0f}}},
9242         {&ps_loop_break, {{1.0f, 1.0f}}, {{1.0f}}},
9243         {&ps_loop_break, {{1.0f, 2.0f}}, {{1.0f}}},
9244         {&ps_loop_break, {{1.0f, 3.0f}}, {{1.0f}}},
9245         {&ps_loop_break, {{7.0f, 0.0f}}, {{1.0f}}},
9246         {&ps_loop_break, {{7.0f, 2.0f}}, {{1.0f}}},
9247         {&ps_loop_break, {{7.0f, 6.0f}}, {{1.0f}}},
9248         {&ps_loop_break, {{7.0f, 7.0f}}, {{7.0f}}},
9249         {&ps_loop_break, {{7.0f, 8.0f}}, {{7.0f}}},
9250         {&ps_loop_break, {{7.0f, 9.0f}}, {{7.0f}}},
9251 
9252         {&ps_loop_ret, {{0.0f, 0.0f}}, {{0.0f}}},
9253         {&ps_loop_ret, {{1.0f, 9.0f}}, {{1.0f}}},
9254         {&ps_loop_ret, {{2.0f, 2.0f}}, {{2.0f}}},
9255         {&ps_loop_ret, {{5.0f, 9.0f}}, {{5.0f}}},
9256         {&ps_loop_ret, {{1.0f, 0.0f}}, {{1.0f, 1.0f, 1.0f, 1.0f}}},
9257         {&ps_loop_ret, {{2.0f, 1.0f}}, {{1.0f, 1.0f, 1.0f, 1.0f}}},
9258         {&ps_loop_ret, {{8.0f, 7.0f}}, {{1.0f, 1.0f, 1.0f, 1.0f}}},
9259 
9260         {&ps_breakc_nz, {{0}}, {{0.0f, 1.0f, 0.0f, 1.0f}}},
9261         {&ps_breakc_z,  {{0}}, {{0.0f, 1.0f, 0.0f, 1.0f}}},
9262 
9263         {&ps_continue,     {{0}}, {{254.0f}}, true},
9264         {&ps_continuec_nz, {{0}}, {{509.0f}}},
9265 
9266         {&ps_retc_nz, {{  0.0f}}, {{1.0f}}},
9267         {&ps_retc_nz, {{ 10.0f}}, {{1.0f}}},
9268         {&ps_retc_nz, {{ 99.0f}}, {{1.0f}}},
9269         {&ps_retc_nz, {{300.0f}}, {{0.0f}}},
9270 
9271         {&ps_src_modifiers, {{ 1.0f,  1.0f,  1.0f,  2.0f}}, {{-1.0f, 1.0f, -1.0f, -2.0f}}},
9272         {&ps_src_modifiers, {{-1.0f, -1.0f, -1.0f, -2.0f}}, {{ 1.0f, 1.0f, -1.0f, -2.0f}}},
9273 
9274         {&ps_sat, {{ 0.0f,  1.0f,     2.0f,      3.0f}}, {{0.0f, 1.0f, 1.0f, 1.0f}}},
9275         {&ps_sat, {{-0.0f, -1.0f,    -2.0f,     -3.0f}}, {{0.0f, 0.0f, 0.0f, 0.0f}}},
9276         {&ps_sat, {{  NAN,  -NAN, INFINITY, -INFINITY}}, {{0.0f, 0.0f, 1.0f, 0.0f}}},
9277 
9278         {&ps_min_max, {{0.0f}, {     1.0f}}, {{     0.0f,     1.0f}}},
9279         {&ps_min_max, {{0.0f}, {    -1.0f}}, {{    -1.0f,     0.0f}}},
9280         {&ps_min_max, {{ NAN}, {     1.0f}}, {{     1.0f,     1.0f}}},
9281         {&ps_min_max, {{0.0f}, {      NAN}}, {{     0.0f,     0.0f}}},
9282         {&ps_min_max, {{0.0f}, { INFINITY}}, {{     0.0f, INFINITY}}},
9283         {&ps_min_max, {{1.0f}, { INFINITY}}, {{     1.0f, INFINITY}}},
9284         {&ps_min_max, {{0.0f}, {-INFINITY}}, {{-INFINITY,     0.0f}}},
9285         {&ps_min_max, {{1.0f}, {-INFINITY}}, {{-INFINITY,     1.0f}}},
9286 
9287         {&ps_ftou, {{     -NAN}}, {.u = { 0,  0 }}},
9288         {&ps_ftou, {{      NAN}}, {.u = { 0,  0 }}},
9289         {&ps_ftou, {{-INFINITY}}, {.u = { 0, ~0u}}},
9290         {&ps_ftou, {{ INFINITY}}, {.u = {~0u, 0 }}},
9291         {&ps_ftou, {{    -1.0f}}, {.u = { 0,  1 }}},
9292         {&ps_ftou, {{     1.0f}}, {.u = { 1,  0 }}},
9293 
9294         {&ps_ftoi, {{     -NAN}}, {.u = {      0,       0}}},
9295         {&ps_ftoi, {{      NAN}}, {.u = {      0,       0}}},
9296         {&ps_ftoi, {{-INFINITY}}, {.u = {INT_MIN, INT_MAX}}},
9297         {&ps_ftoi, {{ INFINITY}}, {.i = {INT_MAX, INT_MIN}}},
9298         {&ps_ftoi, {{    -1.0f}}, {.i = {     -1,       1}}},
9299         {&ps_ftoi, {{     1.0f}}, {.i = {      1,      -1}}},
9300 
9301         {&ps_round, {{    -0.5f}}, {{    -1.0f,      0.0f,     -0.0f}}},
9302         {&ps_round, {{    -0.0f}}, {{    -0.0f,     -0.0f,     -0.0f}}},
9303         {&ps_round, {{     0.0f}}, {{     0.0f,      0.0f,      0.0f}}},
9304         {&ps_round, {{     0.5f}}, {{     0.0f,      1.0f,      0.0f}}},
9305         {&ps_round, {{     3.0f}}, {{     3.0f,      3.0f,      3.0f}}},
9306         {&ps_round, {{ INFINITY}}, {{ INFINITY,  INFINITY,  INFINITY}}},
9307         {&ps_round, {{-INFINITY}}, {{-INFINITY, -INFINITY, -INFINITY}}},
9308 
9309         {&ps_round_ne, {{ 0.0f, -0.0f,  0.5f, -0.5f}}, {{ 0.0f, -0.0f,  0.0f, -0.0f}}},
9310         {&ps_round_ne, {{ 2.0f,  3.0f,  4.0f,  5.0f}}, {{ 2.0f,  3.0f,  4.0f,  5.0f}}},
9311         {&ps_round_ne, {{ 2.4f,  3.4f,  4.4f,  5.4f}}, {{ 2.0f,  3.0f,  4.0f,  5.0f}}},
9312         {&ps_round_ne, {{ 2.5f,  3.5f,  4.5f,  5.5f}}, {{ 2.0f,  4.0f,  4.0f,  6.0f}}},
9313         {&ps_round_ne, {{ 2.6f,  3.6f,  4.6f,  5.6f}}, {{ 3.0f,  4.0f,  5.0f,  6.0f}}},
9314         {&ps_round_ne, {{-2.5f, -3.5f, -4.5f, -5.5f}}, {{-2.0f, -4.0f, -4.0f, -6.0f}}},
9315         {&ps_round_ne, {{-2.4f, -3.4f, -4.4f, -5.4f}}, {{-2.0f, -3.0f, -4.0f, -5.0f}}},
9316         {&ps_round_ne, {{ INFINITY}}, {{ INFINITY}}},
9317         {&ps_round_ne, {{-INFINITY}}, {{-INFINITY}}},
9318 
9319         {&ps_frc, {{ 0.0f}}, {{0.0f, 0.0f}}},
9320         {&ps_frc, {{-0.0f}}, {{0.0f, 0.0f}}},
9321         {&ps_frc, {{ 1.0f}}, {{0.0f, 0.0f}}},
9322         {&ps_frc, {{-1.0f}}, {{0.0f, 0.0f}}},
9323         {&ps_frc, {{ 0.5f}}, {{0.5f, 0.5f}}},
9324         {&ps_frc, {{-0.5f}}, {{0.5f, 0.5f}}},
9325 
9326         {&ps_exp, {{     0.0f}}, {{   1.00f}}},
9327         {&ps_exp, {{    -0.0f}}, {{   1.00f}}},
9328         {&ps_exp, {{     2.0f}}, {{   4.00f}}},
9329         {&ps_exp, {{    -2.0f}}, {{   0.25f}}},
9330         {&ps_exp, {{ INFINITY}}, {{INFINITY}}},
9331         {&ps_exp, {{-INFINITY}}, {{   0.00f}}},
9332 
9333         {&ps_log, {{  -0.00f}}, {{-INFINITY}}},
9334         {&ps_log, {{   0.00f}}, {{-INFINITY}}},
9335         {&ps_log, {{INFINITY}}, {{ INFINITY}}},
9336         {&ps_log, {{   0.25f}}, {{    -2.0f}}},
9337         {&ps_log, {{   0.50f}}, {{    -1.0f}}},
9338         {&ps_log, {{   2.00f}}, {{     1.0f}}},
9339         {&ps_log, {{   8.00f}}, {{     3.0f}}},
9340 
9341         {&ps_rcp, {{-INFINITY}}, {{    -0.0f}}},
9342         {&ps_rcp, {{ INFINITY}}, {{     0.0f}}},
9343         {&ps_rcp, {{    -0.0f}}, {{-INFINITY}}},
9344         {&ps_rcp, {{     0.0f}}, {{ INFINITY}}},
9345         {&ps_rcp, {{    -1.0f}}, {{    -1.0f}}},
9346         {&ps_rcp, {{     1.0f}}, {{     1.0f}}},
9347         {&ps_rcp, {{    -2.0f}}, {{    -0.5f}}},
9348         {&ps_rcp, {{     2.0f}}, {{     0.5f}}},
9349 
9350         {&ps_rcp_vector, {{-1.0f, 1.0f, 4.0f, -4.0f}}, {{-1.0f, 1.0f, 0.25f, -0.25f}}},
9351 
9352         {&ps_sincos, {{ 0.0f, -0.0f,  0.0f, -0.0f}}, {{ 0.0f, -0.0f,  1.0f,  1.0f}}},
9353         {&ps_sincos, {{ 0.0f, -0.0f,  M_PI, -M_PI}}, {{ 0.0f, -0.0f,  1.0f,  1.0f}}},
9354 
9355         {&ps_indexable_temp, {{0.0f}}, {{1.0f, 0.0f, 0.0f,  1.0f}}},
9356         {&ps_indexable_temp, {{1.0f}}, {{0.0f, 1.0f, 0.0f,  1.0f}}},
9357         {&ps_indexable_temp, {{2.0f}}, {{0.0f, 0.0f, 1.0f,  1.0f}}},
9358 
9359         {&ps_indexable_temp2, {{0.0f}}, {{1.0f, 0.0f, 0.0f,  1.0f}}},
9360         {&ps_indexable_temp2, {{1.0f}}, {{0.0f, 1.0f, 0.0f,  1.0f}}},
9361         {&ps_indexable_temp2, {{2.0f}}, {{0.0f, 0.0f, 1.0f,  1.0f}}},
9362         {&ps_indexable_temp2, {{3.0f}}, {{0.0f, 0.0f, 1.0f,  1.0f}}},
9363         {&ps_indexable_temp2, {{4.0f}}, {{0.0f, 1.0f, 0.0f,  1.0f}}},
9364         {&ps_indexable_temp2, {{5.0f}}, {{1.0f, 0.0f, 0.0f,  1.0f}}},
9365         {&ps_indexable_temp2, {{6.0f}}, {{0.0f, 1.0f, 0.0f,  1.0f}}},
9366         {&ps_indexable_temp2, {{7.0f}}, {{0.0f, 1.0f, 0.0f,  1.0f}}},
9367         {&ps_indexable_temp2, {{8.0f}}, {{0.0f, 0.0f, 1.0f,  1.0f}}},
9368         {&ps_indexable_temp2, {{9.0f}}, {{0.0f, 0.0f, 1.0f,  1.0f}}},
9369     };
9370 
9371     static const struct
9372     {
9373         const struct named_shader *ps;
9374         union
9375         {
9376             struct
9377             {
9378                 struct uvec4 src0;
9379                 struct uvec4 src1;
9380                 struct uvec4 src2;
9381             } u;
9382             struct
9383             {
9384                 struct ivec4 src0;
9385                 struct ivec4 src1;
9386                 struct ivec4 src2;
9387             } i;
9388             struct
9389             {
9390                 struct vec4 src0;
9391                 struct vec4 src1;
9392                 struct vec4 src2;
9393             } f;
9394         } input;
9395         union
9396         {
9397             struct uvec4 u;
9398             struct ivec4 i;
9399             struct vec4 f;
9400         } output;
9401         bool skip_on_warp;
9402     }
9403     uint_tests[] =
9404     {
9405         {&ps_bfi, {{{     0,      0,    0,    0}}}, {{         0,          0,          0,          0}}},
9406         {&ps_bfi, {{{     0,      0,    0,    1}}}, {{         1,          1,          1,          1}}},
9407         {&ps_bfi, {{{   ~0u,      0,  ~0u,    0}}}, {{0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}}},
9408         {&ps_bfi, {{{   ~0u,    ~0u,  ~0u,    0}}}, {{0x80000000, 0x80000000, 0x80000000, 0x80000000}}},
9409         {&ps_bfi, {{{   ~0u,  0x1fu,  ~0u,    0}}}, {{0x80000000, 0x80000000, 0x80000000, 0x80000000}}},
9410         {&ps_bfi, {{{   ~0u, ~0x1fu,  ~0u,    0}}}, {{0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}}},
9411         {&ps_bfi, {{{     0,      0, 0xff,    1}}}, {{         1,          1,          1,          1}}},
9412         {&ps_bfi, {{{     0,      0, 0xff,    2}}}, {{         2,          2,          2,          2}}},
9413         {&ps_bfi, {{{    16,     16, 0xff, 0xff}}}, {{0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff}}},
9414         {&ps_bfi, {{{     0,      0,  ~0u,  ~0u}}}, {{       ~0u,        ~0u,        ~0u,        ~0u}}},
9415         {&ps_bfi, {{{~0x1fu,      0,  ~0u,    0}}}, {{         0,          0,          0,          0}}},
9416         {&ps_bfi, {{{~0x1fu,      0,  ~0u,    1}}}, {{         1,          1,          1,          1}}},
9417         {&ps_bfi, {{{~0x1fu,      0,  ~0u,    2}}}, {{         2,          2,          2,          2}}},
9418         {&ps_bfi, {{{     0, ~0x1fu,  ~0u,    0}}}, {{         0,          0,          0,          0}}},
9419         {&ps_bfi, {{{     0, ~0x1fu,  ~0u,    1}}}, {{         1,          1,          1,          1}}},
9420         {&ps_bfi, {{{     0, ~0x1fu,  ~0u,    2}}}, {{         2,          2,          2,          2}}},
9421         {&ps_bfi, {{{~0x1fu, ~0x1fu,  ~0u,    0}}}, {{         0,          0,          0,          0}}},
9422         {&ps_bfi, {{{~0x1fu, ~0x1fu,  ~0u,    1}}}, {{         1,          1,          1,          1}}},
9423         {&ps_bfi, {{{~0x1fu, ~0x1fu,  ~0u,    2}}}, {{         2,          2,          2,          2}}},
9424 
9425         {&ps_ibfe, {{{ 0,  4, 0x00000000}}}, {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9426         {&ps_ibfe, {{{ 0,  4, 0xffffffff}}}, {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9427         {&ps_ibfe, {{{ 0,  4, 0x7fffffff}}}, {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9428         {&ps_ibfe, {{{ 4,  0, 0x00000000}}}, {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9429         {&ps_ibfe, {{{ 4,  0, 0xfffffffa}}}, {{0xfffffffa, 0xfffffffa, 0xfffffffa, 0xfffffffa}}},
9430         {&ps_ibfe, {{{ 4,  0, 0x7ffffffc}}}, {{0xfffffffc, 0xfffffffc, 0xfffffffc, 0xfffffffc}}},
9431         {&ps_ibfe, {{{ 4,  4, 0x00000000}}}, {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9432         {&ps_ibfe, {{{ 4,  4, 0xffffffff}}}, {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9433         {&ps_ibfe, {{{ 4,  4, 0xffffff1f}}}, {{0x00000001, 0x00000001, 0x00000001, 0x00000001}}},
9434         {&ps_ibfe, {{{ 4,  4, 0x7fffffff}}}, {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9435         {&ps_ibfe, {{{23,  8, 0x00000000}}}, {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9436         {&ps_ibfe, {{{23,  8, 0xffffffff}}}, {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9437         {&ps_ibfe, {{{23,  8, 0x7fffffff}}}, {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9438         {&ps_ibfe, {{{30,  1, 0x00000000}}}, {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9439         {&ps_ibfe, {{{30,  1, 0xffffffff}}}, {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9440         {&ps_ibfe, {{{30,  1, 0x7fffffff}}}, {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9441         {&ps_ibfe, {{{15, 15, 0x7fffffff}}}, {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9442         {&ps_ibfe, {{{15, 15, 0x3fffffff}}}, {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9443         {&ps_ibfe, {{{15, 15, 0x1fffffff}}}, {{0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff}}},
9444         {&ps_ibfe, {{{15, 15, 0xffff00ff}}}, {{0xfffffffe, 0xfffffffe, 0xfffffffe, 0xfffffffe}}},
9445         {&ps_ibfe, {{{16, 15, 0xffffffff}}}, {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9446         {&ps_ibfe, {{{16, 15, 0x3fffffff}}}, {{0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff}}},
9447         {&ps_ibfe, {{{20, 15, 0xffffffff}}}, {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9448         {&ps_ibfe, {{{31, 31, 0xffffffff}}}, {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9449         {&ps_ibfe, {{{31, 31, 0x80000000}}}, {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9450         {&ps_ibfe, {{{31, 31, 0x7fffffff}}}, {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9451 
9452         {&ps_ibfe2, {{{16, 15, 0x3fffffff}}}, {{0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff}}},
9453 
9454         {&ps_ubfe, {{{0x00000000}}}, {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9455         {&ps_ubfe, {{{0xffffffff}}}, {{0x0000000f, 0x007fffff, 0x0000007f, 0x3fffffff}}},
9456         {&ps_ubfe, {{{0xff000000}}}, {{0x00000000, 0x007f0000, 0x00000000, 0x3f800000}}},
9457         {&ps_ubfe, {{{0x00ff0000}}}, {{0x00000000, 0x0000ff00, 0x00000000, 0x007f8000}}},
9458         {&ps_ubfe, {{{0x000000ff}}}, {{0x0000000f, 0x00000000, 0x0000007f, 0x0000007f}}},
9459         {&ps_ubfe, {{{0x80000001}}}, {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9460         {&ps_ubfe, {{{0xc0000003}}}, {{0x00000000, 0x00400000, 0x00000001, 0x20000001}}},
9461 
9462         {&ps_bfrev, {{{0x12345678}}}, {{0x1e6a2c48, 0x12345678, 0x1e6a0000, 0x2c480000}}},
9463         {&ps_bfrev, {{{0xffff0000}}}, {{0x0000ffff, 0xffff0000, 0x00000000, 0xffff0000}}},
9464         {&ps_bfrev, {{{0xffffffff}}}, {{0xffffffff, 0xffffffff, 0xffff0000, 0xffff0000}}},
9465 
9466         {&ps_bits, {{{         0,          0}}}, {{ 0, ~0u, ~0u, ~0u}}},
9467         {&ps_bits, {{{       ~0u,        ~0u}}}, {{32,   0,  31, ~0u}}},
9468         {&ps_bits, {{{0x7fffffff, 0x7fffffff}}}, {{31,   0,  30,  30}}},
9469         {&ps_bits, {{{0x80000000, 0x80000000}}}, {{ 1,  31,  31,  30}}},
9470         {&ps_bits, {{{0x00000001, 0x00000001}}}, {{ 1,   0,   0,   0}}},
9471         {&ps_bits, {{{0x80000001, 0x80000001}}}, {{ 2,   0,  31,  30}}},
9472         {&ps_bits, {{{0x88888888, 0x88888888}}}, {{ 8,   3,  31,  30}}},
9473         {&ps_bits, {{{0xcccccccc, 0xcccccccc}}}, {{16,   2,  31,  29}}},
9474         {&ps_bits, {{{0x11111111, 0x11111c11}}}, {{ 8,   0,  28,  28}}},
9475         {&ps_bits, {{{0x0000000f, 0x0000000f}}}, {{ 4,   0,   3,   3}}},
9476         {&ps_bits, {{{0x8000000f, 0x8000000f}}}, {{ 5,   0,  31,  30}}},
9477         {&ps_bits, {{{0x00080000, 0x00080000}}}, {{ 1,  19,  19,  19}}},
9478 
9479         {&ps_ishr, {{{0x00000000, 0x00000000, 0x00000000, 0x00000000}, {~0x1fu, 0, 32, 64}}},
9480                    {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9481         {&ps_ishr, {{{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, {~0x1fu, 0, 32, 64}}},
9482                    {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9483         {&ps_ishr, {{{0xfefefefe, 0x0fefefef, 0x0f0f0f0f, 0x12345678}, {~0x1fu, 0, 32, 64}}},
9484                    {{0xfefefefe, 0x0fefefef, 0x0f0f0f0f, 0x12345678}}},
9485         {&ps_ishr, {{{0x00000000, 0x00000000, 0x00000000, 0x00000000}, {    31, 7, 15, 11}}},
9486                    {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9487         {&ps_ishr, {{{0x80000000, 0x80000000, 0x80000000, 0x80000000}, {    31, 7, 15, 11}}},
9488                    {{0xffffffff, 0xff000000, 0xffff0000, 0xfff00000}}},
9489 
9490         {&ps_ushr, {{{0x00000000, 0x00000000, 0x00000000, 0x00000000}, {~0x1fu, 0, 32, 64}}},
9491                    {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9492         {&ps_ushr, {{{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, {~0x1fu, 0, 32, 64}}},
9493                    {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9494         {&ps_ushr, {{{0xfefefefe, 0x0fefefef, 0x0f0f0f0f, 0x12345678}, {~0x1fu, 0, 32, 64}}},
9495                    {{0xfefefefe, 0x0fefefef, 0x0f0f0f0f, 0x12345678}}},
9496         {&ps_ushr, {{{0x00000000, 0x00000000, 0x00000000, 0x00000000}, {    31, 7, 15, 11}}},
9497                    {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9498         {&ps_ushr, {{{0x80000000, 0x80000000, 0x80000000, 0x80000000}, {    31, 7, 15, 11}}},
9499                    {{0x00000001, 0x01000000, 0x00010000, 0x00100000}}},
9500 
9501         {&ps_ishl, {{{0x00000000, 0x00000000, 0x00000000, 0x00000000}, {~0x1fu, 0, 32, 64}}},
9502                    {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9503         {&ps_ishl, {{{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, {~0x1fu, 0, 32, 64}}},
9504                    {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9505         {&ps_ishl, {{{0xfefefefe, 0x0fefefef, 0x0f0f0f0f, 0x12345678}, {~0x1fu, 0, 32, 64}}},
9506                    {{0xfefefefe, 0x0fefefef, 0x0f0f0f0f, 0x12345678}}},
9507         {&ps_ishl, {{{0x00000000, 0x00000000, 0x00000000, 0x00000000}, {    31, 7, 15, 11}}},
9508                    {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9509         {&ps_ishl, {{{0x80000000, 0x80000000, 0x80000000, 0x80000000}, {    31, 7, 15, 11}}},
9510                    {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9511         {&ps_ishl, {{{0x00000001, 0x00000001, 0x00000001, 0x800feac1}, {    31, 7, 15, 11}}},
9512                    {{0x80000000, 0x00000080, 0x00008000, 0x7f560800}}},
9513 
9514         {&ps_ishl_const, {{{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9515                           {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}},
9516         {&ps_ishl_const, {{{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}},
9517                           {{0xfffffffc, 0xfffffffc, 0xfffffffc, 0xfffffffc}}},
9518 
9519         {&ps_not, {{{0x00000000, 0xffffffff}}}, {{0xffffffff, 0x00000000, 0x00000000, 0xffffffff}}},
9520         {&ps_not, {{{0xf0f0f0f0, 0x0f0f0f0f}}}, {{0x0f0f0f0f, 0xf0f0f0f0, 0xf0f0f0f0, 0x0f0f0f0f}}},
9521 
9522         {&ps_icmp, {.i = {{ 0,  0}}}, {{~0u, ~0u,  0,   0}}},
9523         {&ps_icmp, {.i = {{ 1,  0}}}, {{ 0,  ~0u,  0,  ~0u}}},
9524         {&ps_icmp, {.i = {{ 0,  1}}}, {{ 0,   0,  ~0u, ~0u}}},
9525         {&ps_icmp, {.i = {{ 1,  1}}}, {{~0u, ~0u,  0,   0}}},
9526         {&ps_icmp, {.i = {{-1, -1}}}, {{~0u, ~0u,  0,   0}}},
9527         {&ps_icmp, {.i = {{ 0, -1}}}, {{ 0,  ~0u,  0,  ~0u}}},
9528         {&ps_icmp, {.i = {{-1,  0}}}, {{ 0,   0,  ~0u, ~0u}}},
9529         {&ps_icmp, {.i = {{ 1, -1}}}, {{ 0,  ~0u,  0,  ~0u}}},
9530         {&ps_icmp, {.i = {{-1,  1}}}, {{ 0,   0,  ~0u, ~0u}}},
9531         {&ps_icmp, {.i = {{-2, -1}}}, {{ 0,   0,  ~0u, ~0u}}},
9532 
9533         {&ps_ucmp, {{{0,  0}}}, {{~0u,  0, }}},
9534         {&ps_ucmp, {{{1,  0}}}, {{~0u,  0, }}},
9535         {&ps_ucmp, {{{0,  1}}}, {{ 0,  ~0u,}}},
9536         {&ps_ucmp, {{{1,  1}}}, {{~0u,  0, }}},
9537         {&ps_ucmp, {{{1,  2}}}, {{ 0,  ~0u,}}},
9538 
9539         {&ps_umin_umax, {{{ 0,   0}}},  {{ 0,   0}}},
9540         {&ps_umin_umax, {{{ 0,   1}}},  {{ 0,   1}}},
9541         {&ps_umin_umax, {{{ 1,   0}}},  {{ 0,   1}}},
9542         {&ps_umin_umax, {{{~0u, ~0u}}}, {{~0u, ~0u}}},
9543         {&ps_umin_umax, {{{ 0,  ~0u}}}, {{ 0,  ~0u}}},
9544         {&ps_umin_umax, {{{~0u,  0}}},  {{ 0,  ~0u}}},
9545 
9546         {&ps_f16tof32, {{{0x00000000, 0x00003c00, 0x00005640, 0x00005bd0}}}, {{0, 1, 100, 250}}},
9547         {&ps_f16tof32, {{{0x00010000, 0x00013c00, 0x00015640, 0x00015bd0}}}, {{0, 1, 100, 250}}},
9548         {&ps_f16tof32, {{{0x000f0000, 0x000f3c00, 0x000f5640, 0x000f5bd0}}}, {{0, 1, 100, 250}}},
9549         {&ps_f16tof32, {{{0xffff0000, 0xffff3c00, 0xffff5640, 0xffff5bd0}}}, {{0, 1, 100, 250}}},
9550 
9551         {&ps_f16tof32_2, {{{0x00000000, 0x00003c00, 0x00005640, 0x00005bd0}}}, {{250, 100, 1, 0}}},
9552         {&ps_f16tof32_2, {{{0x00010000, 0x00013c00, 0x00015640, 0x00015bd0}}}, {{250, 100, 1, 0}}},
9553         {&ps_f16tof32_2, {{{0x000f0000, 0x000f3c00, 0x000f5640, 0x000f5bd0}}}, {{250, 100, 1, 0}}},
9554         {&ps_f16tof32_2, {{{0xffff0000, 0xffff3c00, 0xffff5640, 0xffff5bd0}}}, {{250, 100, 1, 0}}},
9555 
9556         {&ps_f32tof16, {.f = {{0.0f, 1.0f, -1.0f, 666.0f}}}, {{0, 0x3c00, 0xbc00, 0x6134}}},
9557 
9558         {&ps_f32tof16_2, {.f = {{0.0f, 1.0f, -1.0f, 666.0f}}}, {{0x6134, 0xbc00, 0x3c00, 0}}},
9559 
9560         {&ps_imad, {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}}, {{ 0,  0,  0,  0}}},
9561         {&ps_imad, {{{0, 0, 0, 0}, {0, 0, 0, 0}, {1, 2, 0, 0}}}, {{ 1,  2,  0,  0}}},
9562         {&ps_imad, {{{2, 3, 4, 5}, {5, 5, 5, 5}, {0, 0, 0, 0}}}, {{10, 15, 20, 25}}},
9563         {&ps_imad, {{{2, 3, 4, 5}, {5, 5, 5, 5}, {5, 5, 6, 6}}}, {{15, 20, 14, 19}}},
9564 
9565         {&ps_imul, {{{0}, { 0u}}}, {{ 0u}}},
9566         {&ps_imul, {{{1}, { 2u}}}, {{ 2u}}},
9567         {&ps_imul, {{{1}, { 3u}}}, {{ 3u}}},
9568         {&ps_imul, {{{6}, { 3u}}}, {{18u}}},
9569         {&ps_imul, {{{1}, {~0u}}}, {{~0u}}},
9570         {&ps_imul, {{{2}, {~0u}}}, {{~1u}}},
9571         {&ps_imul, {{{3}, {~0u}}}, {{~2u}}},
9572 
9573         {&ps_udiv, {{{0}, {0}}}, {{~0u, ~0u}}},
9574         {&ps_udiv, {{{1}, {0}}}, {{~0u, ~0u}}},
9575         {&ps_udiv, {{{1}, {1}}}, {{ 1u,  0u}}},
9576         {&ps_udiv, {{{7}, {1}}}, {{ 7u,  0u}}},
9577         {&ps_udiv, {{{7}, {2}}}, {{ 3u,  1u}}},
9578         {&ps_udiv, {{{7}, {3}}}, {{ 2u,  1u}}},
9579         {&ps_udiv, {{{7}, {4}}}, {{ 1u,  3u}}},
9580         {&ps_udiv, {{{7}, {5}}}, {{ 1u,  2u}}},
9581         {&ps_udiv, {{{7}, {6}}}, {{ 1u,  1u}}},
9582         {&ps_udiv, {{{7}, {7}}}, {{ 1u,  0u}}},
9583 
9584         {&ps_nested_switch, {{{~0u, 0, 0, 0}, {0}}}, {{  1,   0,   0,   0}}},
9585         {&ps_nested_switch, {{{ 0u, 0, 0, 0}, {0}}}, {{  2,   0,   0,   0}}},
9586         {&ps_nested_switch, {{{ 1u, 0, 0, 0}, {0}}}, {{  2,   0,   0,   0}}},
9587         {&ps_nested_switch, {{{ 2u, 0, 0, 0}, {0}}}, {{  2,   0,   0,   0}}},
9588         {&ps_nested_switch, {{{ 0u, 0, 0, 0}, {1}}}, {{  0,   0,   0,   0}}},
9589         {&ps_nested_switch, {{{ 1u, 0, 0, 0}, {2}}}, {{  0,   0,   0,   0}}},
9590         {&ps_nested_switch, {{{ 2u, 0, 0, 0}, {3}}}, {{  0,   0,   0,   0}}},
9591         {&ps_nested_switch, {{{ 3u, 0, 0, 0}, {0}}}, {{  0,   0,   0,   0}}},
9592         {&ps_nested_switch, {{{ 3u, 0, 0, 0}, {1}}}, {{  0,   0,   0,   0}}},
9593         {&ps_nested_switch, {{{ 5u, 1, 2, 3}, {0}}}, {{  0,   0,   0,   0}}},
9594         {&ps_nested_switch, {{{ 6u, 1, 2, 3}, {1}}}, {{  0,   0,   0,   0}}},
9595         {&ps_nested_switch, {{{ 4u, 0, 0, 0}, {0}}}, {{128, 128, 128, 128}}},
9596         {&ps_nested_switch, {{{ 4u, 0, 0, 0}, {1}}}, {{  0,   0,   1,   1}}},
9597         {&ps_nested_switch, {{{ 4u, 1, 0, 0}, {1}}}, {{  0,   0,   1,   1}}},
9598         {&ps_nested_switch, {{{ 4u, 2, 0, 0}, {1}}}, {{  0,   0,   1,   1}}},
9599         {&ps_nested_switch, {{{ 4u, 3, 0, 0}, {1}}}, {{  0,   0,   1,   1}}},
9600         {&ps_nested_switch, {{{ 4u, 0, 0, 1}, {1}}}, {{255, 255, 255, 255}}},
9601         {&ps_nested_switch, {{{ 4u, 1, 0, 1}, {1}}}, {{255, 255, 255, 255}}},
9602         {&ps_nested_switch, {{{ 4u, 2, 0, 1}, {1}}}, {{255, 255, 255, 255}}},
9603         {&ps_nested_switch, {{{ 4u, 3, 0, 1}, {1}}}, {{255, 255, 255, 255}}},
9604         {&ps_nested_switch, {{{ 4u, 0, 1, 1}, {1}}}, {{  2,   2,   2,   2}}},
9605         {&ps_nested_switch, {{{ 4u, 1, 1, 1}, {1}}}, {{  2,   2,   2,   2}}},
9606         {&ps_nested_switch, {{{ 4u, 2, 1, 1}, {1}}}, {{  2,   2,   2,   2}}},
9607         {&ps_nested_switch, {{{ 4u, 3, 1, 1}, {1}}}, {{  2,   2,   2,   2}}},
9608         {&ps_nested_switch, {{{ 4u, 0, 3, 1}, {1}}}, {{  6,   6,   6,   6}}},
9609         {&ps_nested_switch, {{{ 4u, 1, 3, 1}, {1}}}, {{  6,   6,   6,   6}}},
9610         {&ps_nested_switch, {{{ 4u, 2, 3, 1}, {1}}}, {{  6,   6,   6,   6}}},
9611         {&ps_nested_switch, {{{ 4u, 3, 3, 1}, {1}}}, {{  6,   6,   6,   6}}},
9612         {&ps_nested_switch, {{{ 4u, 5, 3, 1}, {1}}}, {{  1,   1,   1,   1}}},
9613         {&ps_nested_switch, {{{ 4u, 6, 3, 1}, {1}}}, {{  1,   1,   1,   1}}},
9614         {&ps_nested_switch, {{{ 4u, 7, 3, 1}, {1}}}, {{  1,   1,   1,   1}}},
9615         {&ps_nested_switch, {{{ 4u, 8, 3, 1}, {1}}}, {{  1,   1,   1,   1}}},
9616 
9617         {&ps_switch_no_default, {{{0}}}, {{1, 1, 1, 1}}},
9618         {&ps_switch_no_default, {{{1}}}, {{3, 3, 3, 3}}},
9619         {&ps_switch_no_default, {{{2}}}, {{3, 3, 3, 3}}},
9620         {&ps_switch_no_default, {{{3}}}, {{2, 2, 2, 2}}},
9621         {&ps_switch_no_default, {{{4}}}, {{3, 3, 3, 3}}},
9622 
9623         {&ps_movc, {{{0, 0, 0, 0}, {1, 2, 3, 4}, {5, 6, 7, 8}}}, {{5, 6, 7, 8}}},
9624         {&ps_movc, {{{0, 0, 0, 1}, {1, 2, 3, 4}, {5, 6, 7, 8}}}, {{5, 6, 7, 4}}},
9625         {&ps_movc, {{{1, 0, 0, 0}, {1, 2, 3, 4}, {5, 6, 7, 8}}}, {{1, 6, 7, 8}}},
9626         {&ps_movc, {{{1, 0, 0, 1}, {1, 2, 3, 4}, {5, 6, 7, 8}}}, {{1, 6, 7, 4}}},
9627         {&ps_movc, {{{0, 1, 1, 0}, {1, 2, 3, 4}, {5, 6, 7, 8}}}, {{5, 2, 3, 8}}},
9628         {&ps_movc, {{{1, 1, 1, 1}, {1, 2, 3, 4}, {5, 6, 7, 8}}}, {{1, 2, 3, 4}}},
9629 
9630         {
9631             &ps_swapc0,
9632             {{{0, 0, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9633             {{0xdead, 0xc0de, 0xffff, 0xeeee}},
9634         },
9635         {
9636             &ps_swapc0,
9637             {{{1, 1, 1, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9638             {{0xaaaa, 0xbbbb, 0xcccc, 0xdddd}},
9639         },
9640         {
9641             &ps_swapc0,
9642             {{{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
9643                     {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9644             {{0xaaaa, 0xbbbb, 0xcccc, 0xdddd}},
9645         },
9646         {
9647             &ps_swapc0,
9648             {{{1, 0, 1, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9649             {{0xaaaa, 0xc0de, 0xcccc, 0xeeee}},
9650         },
9651         {
9652             &ps_swapc0,
9653             {{{1, 0, 0, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9654             {{0xaaaa, 0xc0de, 0xffff, 0xdddd}},
9655         },
9656         {
9657             &ps_swapc0,
9658             {{{1, 0, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9659             {{0xaaaa, 0xc0de, 0xffff, 0xeeee}},
9660         },
9661         {
9662             &ps_swapc0,
9663             {{{0, 1, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9664             {{0xdead, 0xbbbb, 0xffff, 0xeeee}},
9665         },
9666         {
9667             &ps_swapc0,
9668             {{{0, 0, 1, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9669             {{0xdead, 0xc0de, 0xcccc, 0xeeee}},
9670         },
9671         {
9672             &ps_swapc0,
9673             {{{0, 0, 0, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9674             {{0xdead, 0xc0de, 0xffff, 0xdddd}},
9675         },
9676 
9677         {
9678             &ps_swapc1,
9679             {{{0, 0, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9680             {{0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}
9681         },
9682         {
9683             &ps_swapc1,
9684             {{{1, 1, 1, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9685             {{0xdead, 0xc0de, 0xffff, 0xeeee}},
9686         },
9687         {
9688             &ps_swapc1,
9689             {{{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
9690                     {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9691             {{0xdead, 0xc0de, 0xffff, 0xeeee}},
9692         },
9693         {
9694             &ps_swapc1,
9695             {{{1, 0, 1, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9696             {{0xdead, 0xbbbb, 0xffff, 0xdddd}},
9697         },
9698         {
9699             &ps_swapc1,
9700             {{{1, 0, 0, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9701             {{0xdead, 0xbbbb, 0xcccc, 0xeeee}},
9702         },
9703         {
9704             &ps_swapc1,
9705             {{{1, 0, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9706             {{0xdead, 0xbbbb, 0xcccc, 0xdddd}}
9707         },
9708         {
9709             &ps_swapc1,
9710             {{{0, 1, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9711             {{0xaaaa, 0xc0de, 0xcccc, 0xdddd}}
9712         },
9713         {
9714             &ps_swapc1,
9715             {{{0, 0, 1, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9716             {{0xaaaa, 0xbbbb, 0xffff, 0xdddd}}
9717         },
9718         {
9719             &ps_swapc1,
9720             {{{0, 0, 0, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9721             {{0xaaaa, 0xbbbb, 0xcccc, 0xeeee}},
9722         },
9723 
9724         {
9725             &ps_swapc2,
9726             {{{0, 0, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9727             {{0xdead, 0xc0de, 0xffff, 0xeeee}},
9728         },
9729         {
9730             &ps_swapc2,
9731             {{{1, 1, 1, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9732             {{0xaaaa, 0xbbbb, 0xcccc, 0xdddd}},
9733         },
9734         {
9735             &ps_swapc2,
9736             {{{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
9737                     {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9738             {{0xaaaa, 0xbbbb, 0xcccc, 0xdddd}},
9739         },
9740         {
9741             &ps_swapc2,
9742             {{{1, 0, 1, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9743             {{0xaaaa, 0xc0de, 0xcccc, 0xeeee}},
9744         },
9745         {
9746             &ps_swapc2,
9747             {{{1, 0, 0, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9748             {{0xaaaa, 0xc0de, 0xffff, 0xdddd}},
9749         },
9750         {
9751             &ps_swapc2,
9752             {{{1, 0, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9753             {{0xaaaa, 0xc0de, 0xffff, 0xeeee}},
9754         },
9755         {
9756             &ps_swapc2,
9757             {{{0, 1, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9758             {{0xdead, 0xbbbb, 0xffff, 0xeeee}},
9759         },
9760         {
9761             &ps_swapc2,
9762             {{{0, 0, 1, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9763             {{0xdead, 0xc0de, 0xcccc, 0xeeee}},
9764         },
9765         {
9766             &ps_swapc2,
9767             {{{0, 0, 0, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9768             {{0xdead, 0xc0de, 0xffff, 0xdddd}},
9769         },
9770 
9771         {
9772             &ps_swapc3,
9773             {{{0, 0, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9774             {{0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}
9775         },
9776         {
9777             &ps_swapc3,
9778             {{{1, 1, 1, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9779             {{0xdead, 0xc0de, 0xffff, 0xeeee}},
9780         },
9781         {
9782             &ps_swapc3,
9783             {{{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
9784                     {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9785             {{0xdead, 0xc0de, 0xffff, 0xeeee}},
9786         },
9787         {
9788             &ps_swapc3,
9789             {{{1, 0, 1, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9790             {{0xdead, 0xbbbb, 0xffff, 0xdddd}},
9791         },
9792         {
9793             &ps_swapc3,
9794             {{{1, 0, 0, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9795             {{0xdead, 0xbbbb, 0xcccc, 0xeeee}},
9796         },
9797         {
9798             &ps_swapc3,
9799             {{{1, 0, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9800             {{0xdead, 0xbbbb, 0xcccc, 0xdddd}}
9801         },
9802         {
9803             &ps_swapc3,
9804             {{{0, 1, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9805             {{0xaaaa, 0xc0de, 0xcccc, 0xdddd}}
9806         },
9807         {
9808             &ps_swapc3,
9809             {{{0, 0, 1, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9810             {{0xaaaa, 0xbbbb, 0xffff, 0xdddd}}
9811         },
9812         {
9813             &ps_swapc3,
9814             {{{0, 0, 0, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9815             {{0xaaaa, 0xbbbb, 0xcccc, 0xeeee}},
9816         },
9817 
9818         {
9819             &ps_swapc4,
9820             {{{0, 0, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9821             {{0xdead, 0xc0de, 0xffff, 0xeeee}},
9822         },
9823         {
9824             &ps_swapc4,
9825             {{{1, 1, 1, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9826             {{0xaaaa, 0xbbbb, 0xcccc, 0xdddd}},
9827         },
9828         {
9829             &ps_swapc4,
9830             {{{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
9831                     {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9832             {{0xaaaa, 0xbbbb, 0xcccc, 0xdddd}},
9833         },
9834         {
9835             &ps_swapc4,
9836             {{{1, 0, 1, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9837             {{0xaaaa, 0xc0de, 0xcccc, 0xeeee}},
9838         },
9839         {
9840             &ps_swapc4,
9841             {{{1, 0, 0, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9842             {{0xaaaa, 0xc0de, 0xffff, 0xdddd}},
9843         },
9844         {
9845             &ps_swapc4,
9846             {{{1, 0, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9847             {{0xaaaa, 0xc0de, 0xffff, 0xeeee}},
9848         },
9849         {
9850             &ps_swapc4,
9851             {{{0, 1, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9852             {{0xdead, 0xbbbb, 0xffff, 0xeeee}},
9853         },
9854         {
9855             &ps_swapc4,
9856             {{{0, 0, 1, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9857             {{0xdead, 0xc0de, 0xcccc, 0xeeee}},
9858         },
9859         {
9860             &ps_swapc4,
9861             {{{0, 0, 0, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9862             {{0xdead, 0xc0de, 0xffff, 0xdddd}},
9863         },
9864 
9865         {
9866             &ps_swapc5,
9867             {{{0, 0, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9868             {{0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}
9869         },
9870         {
9871             &ps_swapc5,
9872             {{{1, 1, 1, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9873             {{0xdead, 0xc0de, 0xffff, 0xeeee}},
9874         },
9875         {
9876             &ps_swapc5,
9877             {{{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
9878                     {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9879             {{0xdead, 0xc0de, 0xffff, 0xeeee}},
9880         },
9881         {
9882             &ps_swapc5,
9883             {{{1, 0, 1, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9884             {{0xdead, 0xbbbb, 0xffff, 0xdddd}},
9885         },
9886         {
9887             &ps_swapc5,
9888             {{{1, 0, 0, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9889             {{0xdead, 0xbbbb, 0xcccc, 0xeeee}},
9890         },
9891         {
9892             &ps_swapc5,
9893             {{{1, 0, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9894             {{0xdead, 0xbbbb, 0xcccc, 0xdddd}}
9895         },
9896         {
9897             &ps_swapc5,
9898             {{{0, 1, 0, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9899             {{0xaaaa, 0xc0de, 0xcccc, 0xdddd}}
9900         },
9901         {
9902             &ps_swapc5,
9903             {{{0, 0, 1, 0}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9904             {{0xaaaa, 0xbbbb, 0xffff, 0xdddd}}
9905         },
9906         {
9907             &ps_swapc5,
9908             {{{0, 0, 0, 1}, {0xdead, 0xc0de, 0xffff, 0xeeee}, {0xaaaa, 0xbbbb, 0xcccc, 0xdddd}}},
9909             {{0xaaaa, 0xbbbb, 0xcccc, 0xeeee}},
9910         },
9911     };
9912 
9913     STATIC_ASSERT(sizeof(tests->input) == sizeof(uint_tests->input));
9914 
9915     memset(&desc, 0, sizeof(desc));
9916     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
9917     desc.no_root_signature = true;
9918     if (!init_test_context(&context, &desc))
9919         return;
9920     command_list = context.list;
9921     queue = context.queue;
9922 
9923     context.root_signature = create_cb_root_signature(context.device,
9924             0, D3D12_SHADER_VISIBILITY_PIXEL, D3D12_ROOT_SIGNATURE_FLAG_NONE);
9925 
9926     cb = create_upload_buffer(context.device, sizeof(tests->input), NULL);
9927 
9928     current_ps = NULL;
9929     for (i = 0; i < ARRAY_SIZE(tests); ++i)
9930     {
9931         vkd3d_test_set_context("%u:%s", i, tests[i].ps->name);
9932 
9933         if (tests[i].skip_on_warp && use_warp_device)
9934         {
9935             skip("Skipping shader '%s' test on WARP.\n", tests[i].ps->name);
9936             continue;
9937         }
9938 
9939         if (current_ps != tests[i].ps)
9940         {
9941             if (context.pipeline_state)
9942                 ID3D12PipelineState_Release(context.pipeline_state);
9943             current_ps = tests[i].ps;
9944             shader.pShaderBytecode = current_ps->code;
9945             shader.BytecodeLength = current_ps->size;
9946             context.pipeline_state = create_pipeline_state(context.device,
9947                     context.root_signature, desc.rt_format, NULL, &shader, NULL);
9948         }
9949 
9950         update_buffer_data(cb, 0, sizeof(tests[i].input), &tests[i].input);
9951 
9952         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
9953 
9954         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
9955         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
9956         ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
9957                 ID3D12Resource_GetGPUVirtualAddress(cb));
9958         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
9959         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
9960         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
9961         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
9962         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
9963 
9964         transition_resource_state(command_list, context.render_target,
9965                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
9966         bug_if(tests[i].is_mesa_bug && is_mesa_device(context.device))
9967         check_sub_resource_vec4(context.render_target, 0, queue, command_list, &tests[i].output.f, 2);
9968 
9969         reset_command_list(command_list, context.allocator);
9970         transition_resource_state(command_list, context.render_target,
9971                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
9972     }
9973     vkd3d_test_set_context(NULL);
9974 
9975     hr = ID3D12GraphicsCommandList_Close(command_list);
9976     ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr);
9977     reset_command_list(command_list, context.allocator);
9978     ID3D12Resource_Release(context.render_target);
9979     desc.rt_format = DXGI_FORMAT_R32G32B32A32_UINT;
9980     create_render_target(&context, &desc, &context.render_target, &context.rtv);
9981 
9982     for (i = 0; i < ARRAY_SIZE(uint_tests); ++i)
9983     {
9984         vkd3d_test_set_context("%u:%s", i, uint_tests[i].ps->name);
9985 
9986         if (uint_tests[i].skip_on_warp && use_warp_device)
9987         {
9988             skip("Skipping shader '%s' test on WARP.\n", uint_tests[i].ps->name);
9989             continue;
9990         }
9991 
9992         if (current_ps != uint_tests[i].ps)
9993         {
9994             if (context.pipeline_state)
9995                 ID3D12PipelineState_Release(context.pipeline_state);
9996             current_ps = uint_tests[i].ps;
9997             shader.pShaderBytecode = current_ps->code;
9998             shader.BytecodeLength = current_ps->size;
9999             context.pipeline_state = create_pipeline_state(context.device,
10000                     context.root_signature, desc.rt_format, NULL, &shader, NULL);
10001         }
10002 
10003         update_buffer_data(cb, 0, sizeof(uint_tests[i].input), &uint_tests[i].input);
10004 
10005         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
10006 
10007         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
10008         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
10009         ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
10010                 ID3D12Resource_GetGPUVirtualAddress(cb));
10011         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
10012         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
10013         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
10014         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
10015         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
10016 
10017         transition_resource_state(command_list, context.render_target,
10018                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
10019         check_sub_resource_uvec4(context.render_target, 0, queue, command_list, &uint_tests[i].output.u);
10020 
10021         reset_command_list(command_list, context.allocator);
10022         transition_resource_state(command_list, context.render_target,
10023                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
10024     }
10025     vkd3d_test_set_context(NULL);
10026 
10027     ID3D12Resource_Release(cb);
10028     destroy_test_context(&context);
10029 }
10030 
test_compute_shader_instructions(void)10031 static void test_compute_shader_instructions(void)
10032 {
10033     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
10034     const D3D12_SHADER_BYTECODE *current_cs;
10035     ID3D12GraphicsCommandList *command_list;
10036     D3D12_ROOT_PARAMETER root_parameters[2];
10037     struct resource_readback rb;
10038     struct test_context context;
10039     ID3D12CommandQueue *queue;
10040     ID3D12Resource *buffer;
10041     ID3D12Device *device;
10042     unsigned int i, j;
10043     uint32_t value;
10044     HRESULT hr;
10045 
10046     static const DWORD cs_atomic_iadd_tgsm_raw_code[] =
10047     {
10048 #if 0
10049         RWByteAddressBuffer buffer;
10050 
10051         groupshared uint m0;
10052         groupshared uint m1;
10053 
10054         uint4 u;
10055         int4 s;
10056 
10057         [numthreads(1, 1, 1)]
10058         void main()
10059         {
10060             m0 = buffer.Load(0 * 4);
10061             m1 = buffer.Load(1 * 4);
10062 
10063             InterlockedAdd(m0, u.x);
10064             InterlockedAdd(m1, s.x);
10065 
10066             GroupMemoryBarrierWithGroupSync();
10067 
10068             buffer.Store(0 * 4, m0);
10069             buffer.Store(1 * 4, m1);
10070         }
10071 #endif
10072         0x43425844, 0xcd7bfbec, 0x273e77a4, 0x49b75eb9, 0xe7d291f4, 0x00000001, 0x000001d0, 0x00000003,
10073         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
10074         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x0000017c, 0x00050050, 0x0000005f, 0x0100086a,
10075         0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0300009d, 0x0011e000, 0x00000000, 0x02000068,
10076         0x00000001, 0x0400009f, 0x0011f000, 0x00000000, 0x00000004, 0x0400009f, 0x0011f000, 0x00000001,
10077         0x00000004, 0x0400009b, 0x00000001, 0x00000001, 0x00000001, 0x890000a5, 0x800002c2, 0x00199983,
10078         0x00100012, 0x00000000, 0x00004001, 0x00000000, 0x0011e006, 0x00000000, 0x070000a6, 0x0011f012,
10079         0x00000000, 0x00004001, 0x00000000, 0x0010000a, 0x00000000, 0x080000ad, 0x0011f000, 0x00000000,
10080         0x00004001, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x890000a5, 0x800002c2, 0x00199983,
10081         0x00100012, 0x00000000, 0x00004001, 0x00000004, 0x0011e006, 0x00000000, 0x070000a6, 0x0011f012,
10082         0x00000001, 0x00004001, 0x00000000, 0x0010000a, 0x00000000, 0x080000ad, 0x0011f000, 0x00000001,
10083         0x00004001, 0x00000000, 0x0020800a, 0x00000000, 0x00000001, 0x010018be, 0x070000a5, 0x00100022,
10084         0x00000000, 0x00004001, 0x00000000, 0x0011f006, 0x00000001, 0x070000a5, 0x00100012, 0x00000000,
10085         0x00004001, 0x00000000, 0x0011f006, 0x00000000, 0x070000a6, 0x0011e032, 0x00000000, 0x00004001,
10086         0x00000000, 0x00100046, 0x00000000, 0x0100003e,
10087     };
10088     static D3D12_SHADER_BYTECODE cs_atomic_iadd_tgsm_raw
10089             = {cs_atomic_iadd_tgsm_raw_code, sizeof(cs_atomic_iadd_tgsm_raw_code)};
10090     static const DWORD cs_atomic_iadd_const_code[] =
10091     {
10092 #if 0
10093         RWByteAddressBuffer buffer;
10094 
10095         groupshared uint m;
10096 
10097         [numthreads(1, 1, 1)]
10098         void main()
10099         {
10100             m = buffer.Load(0 * 4);
10101 
10102             InterlockedAdd(m, -1);
10103             buffer.InterlockedAdd(1 * 4, -1);
10104 
10105             GroupMemoryBarrierWithGroupSync();
10106 
10107             buffer.Store(0 * 4, m);
10108         }
10109 #endif
10110         0x43425844, 0x85f9168a, 0x5fe0c4d5, 0x5989b572, 0xecb6ce3c, 0x00000001, 0x0000014c, 0x00000003,
10111         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
10112         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000f8, 0x00050050, 0x0000003e, 0x0100086a,
10113         0x0300009d, 0x0011e000, 0x00000000, 0x02000068, 0x00000001, 0x0400009f, 0x0011f000, 0x00000000,
10114         0x00000004, 0x0400009b, 0x00000001, 0x00000001, 0x00000001, 0x890000a5, 0x800002c2, 0x00199983,
10115         0x00100012, 0x00000000, 0x00004001, 0x00000000, 0x0011e006, 0x00000000, 0x070000a6, 0x0011f012,
10116         0x00000000, 0x00004001, 0x00000000, 0x0010000a, 0x00000000, 0x070000ad, 0x0011f000, 0x00000000,
10117         0x00004001, 0x00000000, 0x00004001, 0xffffffff, 0x070000ad, 0x0011e000, 0x00000000, 0x00004001,
10118         0x00000004, 0x00004001, 0xffffffff, 0x010018be, 0x070000a5, 0x00100012, 0x00000000, 0x00004001,
10119         0x00000000, 0x0011f006, 0x00000000, 0x070000a6, 0x0011e012, 0x00000000, 0x00004001, 0x00000000,
10120         0x0010000a, 0x00000000, 0x0100003e,
10121     };
10122     static const D3D12_SHADER_BYTECODE cs_atomic_iadd_const
10123             = {cs_atomic_iadd_const_code, sizeof(cs_atomic_iadd_const_code)};
10124     static const struct
10125     {
10126         const D3D12_SHADER_BYTECODE *cs;
10127         struct uvec4 u;
10128         struct ivec4 s;
10129         uint32_t input_data[10];
10130         uint32_t expected_data[10];
10131     }
10132     tests[] =
10133     {
10134         {&cs_atomic_iadd_tgsm_raw, {         0}, { 0}, {0, 0}, {0, 0}},
10135         {&cs_atomic_iadd_tgsm_raw, {         0}, { 0}, {1, 1}, {1, 1}},
10136         {&cs_atomic_iadd_tgsm_raw, {         1}, { 1}, {0, 0}, {1, 1}},
10137         {&cs_atomic_iadd_tgsm_raw, {0xffffffff}, {-1}, {1, 1}, {0, 0}},
10138         {&cs_atomic_iadd_tgsm_raw, {0xffffffff}, {-1}, {4, 4}, {3, 3}},
10139 
10140         {&cs_atomic_iadd_const, {0}, {0}, {0x00000000, 0x00000000}, {0xffffffff, 0xffffffff}},
10141         {&cs_atomic_iadd_const, {0}, {0}, {0x00000001, 0x00000001}, {0x00000000, 0x00000000}},
10142         {&cs_atomic_iadd_const, {0}, {0}, {0xffffffff, 0xffffffff}, {0xfffffffe, 0xfffffffe}},
10143     };
10144 
10145     if (!init_compute_test_context(&context))
10146         return;
10147     device = context.device;
10148     command_list = context.list;
10149     queue = context.queue;
10150 
10151     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
10152     root_parameters[0].Descriptor.ShaderRegister = 0;
10153     root_parameters[0].Descriptor.RegisterSpace = 0;
10154     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
10155     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
10156     root_parameters[1].Constants.ShaderRegister = 0;
10157     root_parameters[1].Constants.RegisterSpace = 0;
10158     root_parameters[1].Constants.Num32BitValues = 8;
10159     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
10160     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
10161     root_signature_desc.pParameters = root_parameters;
10162     root_signature_desc.NumStaticSamplers = 0;
10163     root_signature_desc.pStaticSamplers = NULL;
10164     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
10165     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
10166     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
10167 
10168     buffer = create_default_buffer(device, 512,
10169             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
10170 
10171     current_cs = NULL;
10172     for (i = 0; i < ARRAY_SIZE(tests); ++i)
10173     {
10174         if (current_cs != tests[i].cs)
10175         {
10176             if (context.pipeline_state)
10177                 ID3D12PipelineState_Release(context.pipeline_state);
10178             current_cs = tests[i].cs;
10179             context.pipeline_state = create_compute_pipeline_state(device,
10180                     context.root_signature, *current_cs);
10181         }
10182 
10183         upload_buffer_data(buffer, 0, sizeof(tests[i].input_data), tests[i].input_data,
10184                 queue, command_list);
10185         reset_command_list(command_list, context.allocator);
10186         transition_resource_state(command_list, buffer,
10187                     D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
10188 
10189         ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
10190         ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list,
10191                 0, ID3D12Resource_GetGPUVirtualAddress(buffer));
10192         ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(command_list, 1, 4, &tests[i].u, 0);
10193         ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(command_list, 1, 4, &tests[i].s, 4);
10194 
10195         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
10196         ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
10197 
10198         transition_resource_state(command_list, buffer,
10199                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
10200         get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
10201         for (j = 0; j < ARRAY_SIZE(tests[i].expected_data); ++j)
10202         {
10203             value = get_readback_uint(&rb, j, 0, 0);
10204             ok(value == tests[i].expected_data[j], "Test %u: Got 0x%08x, expected 0x%08x at %u.\n",
10205                     i, value, tests[i].expected_data[j], j);
10206         }
10207         release_resource_readback(&rb);
10208         reset_command_list(command_list, context.allocator);
10209         transition_resource_state(command_list, buffer,
10210                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_COPY_DEST);
10211     }
10212 
10213     ID3D12Resource_Release(buffer);
10214     destroy_test_context(&context);
10215 }
10216 
test_discard_instruction(void)10217 static void test_discard_instruction(void)
10218 {
10219     ID3D12PipelineState *pso_discard_nz, *pso_discard_z;
10220     ID3D12GraphicsCommandList *command_list;
10221     struct test_context_desc desc;
10222     struct test_context context;
10223     ID3D12CommandQueue *queue;
10224     ID3D12Device *device;
10225     ID3D12Resource *cb;
10226     unsigned int i;
10227 
10228     static const DWORD ps_discard_nz_code[] =
10229     {
10230 #if 0
10231         uint data;
10232 
10233         float4 main() : SV_Target
10234         {
10235             if (data)
10236                 discard;
10237             return float4(0.0f, 0.5f, 0.0f, 1.0f);
10238         }
10239 #endif
10240         0x43425844, 0xfa7e5758, 0xd8716ffc, 0x5ad6a940, 0x2b99bba2, 0x00000001, 0x000000d0, 0x00000003,
10241         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
10242         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
10243         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000058, 0x00000040, 0x00000016,
10244         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x0404000d,
10245         0x0020800a, 0x00000000, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000,
10246         0x3f000000, 0x00000000, 0x3f800000, 0x0100003e,
10247     };
10248     static const D3D12_SHADER_BYTECODE ps_discard_nz = {ps_discard_nz_code, sizeof(ps_discard_nz_code)};
10249     static const DWORD ps_discard_z_code[] =
10250     {
10251 #if 0
10252         uint data;
10253 
10254         float4 main() : SV_Target
10255         {
10256             if (!data)
10257                 discard;
10258             return float4(0.0f, 1.0f, 0.0f, 1.0f);
10259         }
10260 #endif
10261         0x43425844, 0x5c4dd108, 0x1eb43558, 0x7c02c98c, 0xd81eb34c, 0x00000001, 0x000000d0, 0x00000003,
10262         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
10263         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
10264         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000058, 0x00000040, 0x00000016,
10265         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x0400000d,
10266         0x0020800a, 0x00000000, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000,
10267         0x3f800000, 0x00000000, 0x3f800000, 0x0100003e,
10268     };
10269     static const D3D12_SHADER_BYTECODE ps_discard_z = {ps_discard_z_code, sizeof(ps_discard_z_code)};
10270     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
10271     static const struct uvec4 values[] =
10272     {
10273         {0x0000000},
10274         {0x0000001},
10275         {0x8000000},
10276         {0xfffffff},
10277     };
10278 
10279     memset(&desc, 0, sizeof(desc));
10280     desc.no_root_signature = true;
10281     if (!init_test_context(&context, &desc))
10282         return;
10283     device = context.device;
10284     command_list = context.list;
10285     queue = context.queue;
10286 
10287     context.root_signature = create_cb_root_signature(device,
10288             0, D3D12_SHADER_VISIBILITY_PIXEL, D3D12_ROOT_SIGNATURE_FLAG_NONE);
10289     pso_discard_nz = create_pipeline_state(device, context.root_signature,
10290             context.render_target_desc.Format, NULL, &ps_discard_nz, NULL);
10291     pso_discard_z = create_pipeline_state(device, context.root_signature,
10292             context.render_target_desc.Format, NULL, &ps_discard_z, NULL);
10293 
10294     cb = create_upload_buffer(device, sizeof(*values), NULL);
10295 
10296     for (i = 0; i < ARRAY_SIZE(values); ++i)
10297     {
10298         update_buffer_data(cb, 0, sizeof(values[i]), &values[i]);
10299 
10300         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
10301         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
10302         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
10303         ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
10304                 ID3D12Resource_GetGPUVirtualAddress(cb));
10305         ID3D12GraphicsCommandList_SetPipelineState(command_list, pso_discard_nz);
10306         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
10307         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
10308         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
10309         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
10310         transition_resource_state(command_list, context.render_target,
10311                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
10312         check_sub_resource_uint(context.render_target, 0, queue, command_list,
10313                 values[i].x ? 0xffffffff : 0xff007f00, 1);
10314         reset_command_list(command_list, context.allocator);
10315         transition_resource_state(command_list, context.render_target,
10316                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
10317 
10318         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
10319         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
10320         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
10321         ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
10322                 ID3D12Resource_GetGPUVirtualAddress(cb));
10323         ID3D12GraphicsCommandList_SetPipelineState(command_list, pso_discard_z);
10324         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
10325         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
10326         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
10327         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
10328         transition_resource_state(command_list, context.render_target,
10329                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
10330         check_sub_resource_uint(context.render_target, 0, queue, command_list,
10331                 values[i].x ? 0xff00ff00 : 0xffffffff, 1);
10332         reset_command_list(command_list, context.allocator);
10333         transition_resource_state(command_list, context.render_target,
10334                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
10335     }
10336 
10337     ID3D12Resource_Release(cb);
10338     ID3D12PipelineState_Release(pso_discard_nz);
10339     ID3D12PipelineState_Release(pso_discard_z);
10340     destroy_test_context(&context);
10341 }
10342 
test_shader_interstage_interface(void)10343 static void test_shader_interstage_interface(void)
10344 {
10345     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
10346     ID3D12GraphicsCommandList *command_list;
10347     D3D12_INPUT_LAYOUT_DESC input_layout;
10348     struct test_context_desc desc;
10349     D3D12_VERTEX_BUFFER_VIEW vbv;
10350     struct test_context context;
10351     ID3D12CommandQueue *queue;
10352     ID3D12Resource *vb;
10353 
10354     static const DWORD vs_code[] =
10355     {
10356 #if 0
10357         struct vertex
10358         {
10359             float4 position : SV_Position;
10360             float2 t0 : TEXCOORD0;
10361             nointerpolation float t1 : TEXCOORD1;
10362             uint t2 : TEXCOORD2;
10363             uint t3 : TEXCOORD3;
10364             float t4 : TEXCOORD4;
10365         };
10366 
10367         void main(in vertex vin, out vertex vout)
10368         {
10369             vout = vin;
10370         }
10371 #endif
10372         0x43425844, 0x561ea178, 0x7b8f454c, 0x69091b4f, 0xf28d9a01, 0x00000001, 0x000002c0, 0x00000003,
10373         0x0000002c, 0x000000e4, 0x0000019c, 0x4e475349, 0x000000b0, 0x00000006, 0x00000008, 0x00000098,
10374         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x000000a4, 0x00000000, 0x00000000,
10375         0x00000003, 0x00000001, 0x00000303, 0x000000a4, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
10376         0x00000101, 0x000000a4, 0x00000002, 0x00000000, 0x00000001, 0x00000003, 0x00000101, 0x000000a4,
10377         0x00000003, 0x00000000, 0x00000001, 0x00000004, 0x00000101, 0x000000a4, 0x00000004, 0x00000000,
10378         0x00000003, 0x00000005, 0x00000101, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f,
10379         0xababab00, 0x4e47534f, 0x000000b0, 0x00000006, 0x00000008, 0x00000098, 0x00000000, 0x00000001,
10380         0x00000003, 0x00000000, 0x0000000f, 0x000000a4, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
10381         0x00000c03, 0x000000a4, 0x00000004, 0x00000000, 0x00000003, 0x00000001, 0x00000b04, 0x000000a4,
10382         0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x00000e01, 0x000000a4, 0x00000002, 0x00000000,
10383         0x00000001, 0x00000002, 0x00000d02, 0x000000a4, 0x00000003, 0x00000000, 0x00000001, 0x00000002,
10384         0x00000b04, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x58454853,
10385         0x0000011c, 0x00010050, 0x00000047, 0x0100086a, 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f,
10386         0x00101032, 0x00000001, 0x0300005f, 0x00101012, 0x00000002, 0x0300005f, 0x00101012, 0x00000003,
10387         0x0300005f, 0x00101012, 0x00000004, 0x0300005f, 0x00101012, 0x00000005, 0x04000067, 0x001020f2,
10388         0x00000000, 0x00000001, 0x03000065, 0x00102032, 0x00000001, 0x03000065, 0x00102042, 0x00000001,
10389         0x03000065, 0x00102012, 0x00000002, 0x03000065, 0x00102022, 0x00000002, 0x03000065, 0x00102042,
10390         0x00000002, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x00102032,
10391         0x00000001, 0x00101046, 0x00000001, 0x05000036, 0x00102042, 0x00000001, 0x0010100a, 0x00000005,
10392         0x05000036, 0x00102012, 0x00000002, 0x0010100a, 0x00000002, 0x05000036, 0x00102022, 0x00000002,
10393         0x0010100a, 0x00000003, 0x05000036, 0x00102042, 0x00000002, 0x0010100a, 0x00000004, 0x0100003e,
10394     };
10395     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
10396     static const DWORD ps_code[] =
10397     {
10398 #if 0
10399         void main(float4 position : SV_Position, float2 t0 : TEXCOORD0,
10400                 nointerpolation float t1 : TEXCOORD1, uint t2 : TEXCOORD2,
10401                 uint t3 : TEXCOORD3, float t4 : TEXCOORD4, out float4 o : SV_Target)
10402         {
10403             o.x = t0.y + t1;
10404             o.y = t2 + t3;
10405             o.z = t4;
10406             o.w = t0.x;
10407         }
10408 #endif
10409         0x43425844, 0x21076b15, 0x493d36f1, 0x0cd125d6, 0x1e92c724, 0x00000001, 0x000001e0, 0x00000003,
10410         0x0000002c, 0x000000e4, 0x00000118, 0x4e475349, 0x000000b0, 0x00000006, 0x00000008, 0x00000098,
10411         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x000000a4, 0x00000000, 0x00000000,
10412         0x00000003, 0x00000001, 0x00000303, 0x000000a4, 0x00000004, 0x00000000, 0x00000003, 0x00000001,
10413         0x00000404, 0x000000a4, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x00000101, 0x000000a4,
10414         0x00000002, 0x00000000, 0x00000001, 0x00000002, 0x00000202, 0x000000a4, 0x00000003, 0x00000000,
10415         0x00000001, 0x00000002, 0x00000404, 0x505f5653, 0x7469736f, 0x006e6f69, 0x43584554, 0x44524f4f,
10416         0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
10417         0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000c0,
10418         0x00000050, 0x00000030, 0x0100086a, 0x03001062, 0x00101032, 0x00000001, 0x03001062, 0x00101042,
10419         0x00000001, 0x03000862, 0x00101012, 0x00000002, 0x03000862, 0x00101022, 0x00000002, 0x03000862,
10420         0x00101042, 0x00000002, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0700001e,
10421         0x00100012, 0x00000000, 0x0010101a, 0x00000002, 0x0010102a, 0x00000002, 0x05000056, 0x00102022,
10422         0x00000000, 0x0010000a, 0x00000000, 0x07000000, 0x00102012, 0x00000000, 0x0010101a, 0x00000001,
10423         0x0010100a, 0x00000002, 0x05000036, 0x001020c2, 0x00000000, 0x001012a6, 0x00000001, 0x0100003e,
10424     };
10425     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
10426     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
10427     {
10428         {"SV_POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0,  0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
10429         {"TEXCOORD",    0, DXGI_FORMAT_R32G32_FLOAT, 0,  8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
10430         {"TEXCOORD",    1, DXGI_FORMAT_R32_FLOAT,    0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
10431         {"TEXCOORD",    2, DXGI_FORMAT_R32_UINT,     0, 20, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
10432         {"TEXCOORD",    3, DXGI_FORMAT_R32_UINT,     0, 24, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
10433         {"TEXCOORD",    4, DXGI_FORMAT_R32_FLOAT,    0, 28, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
10434     };
10435     static const struct
10436     {
10437         struct vec2 position;
10438         struct vec2 t0;
10439         float t1;
10440         unsigned int t2;
10441         unsigned int t3;
10442         float t4;
10443     }
10444     quad[] =
10445     {
10446         {{-1.0f, -1.0f}, {3.0f, 5.0f}, 5.0f, 2, 6, 7.0f},
10447         {{-1.0f,  1.0f}, {3.0f, 5.0f}, 5.0f, 2, 6, 7.0f},
10448         {{ 1.0f, -1.0f}, {3.0f, 5.0f}, 5.0f, 2, 6, 7.0f},
10449         {{ 1.0f,  1.0f}, {3.0f, 5.0f}, 5.0f, 2, 6, 7.0f},
10450     };
10451     static const struct vec4 expected_result = {10.0f, 8.0f, 7.0f, 3.0f};
10452 
10453     memset(&desc, 0, sizeof(desc));
10454     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
10455     desc.no_root_signature = true;
10456     if (!init_test_context(&context, &desc))
10457         return;
10458     command_list = context.list;
10459     queue = context.queue;
10460 
10461     context.root_signature = create_empty_root_signature(context.device,
10462             D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
10463 
10464     input_layout.pInputElementDescs = layout_desc;
10465     input_layout.NumElements = ARRAY_SIZE(layout_desc);
10466     context.pipeline_state = create_pipeline_state(context.device,
10467             context.root_signature, desc.rt_format, &vs, &ps, &input_layout);
10468 
10469     vb = create_upload_buffer(context.device, sizeof(quad), quad);
10470 
10471     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
10472     vbv.StrideInBytes = sizeof(*quad);
10473     vbv.SizeInBytes = sizeof(quad);
10474 
10475     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
10476 
10477     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
10478     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
10479     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
10480     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
10481     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
10482     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
10483     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
10484     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
10485 
10486     transition_resource_state(command_list, context.render_target,
10487             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
10488     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_result, 0);
10489 
10490     ID3D12Resource_Release(vb);
10491     destroy_test_context(&context);
10492 }
10493 
test_shader_input_output_components(void)10494 static void test_shader_input_output_components(void)
10495 {
10496     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
10497     ID3D12GraphicsCommandList *command_list;
10498     D3D12_INPUT_LAYOUT_DESC input_layout;
10499     D3D12_CPU_DESCRIPTOR_HANDLE rtvs[2];
10500     ID3D12Resource *uint_render_target;
10501     struct test_context_desc desc;
10502     D3D12_VERTEX_BUFFER_VIEW vbv;
10503     struct test_context context;
10504     ID3D12CommandQueue *queue;
10505     ID3D12Resource *vb;
10506     unsigned int i;
10507     HRESULT hr;
10508 
10509     static const DWORD vs1_code[] =
10510     {
10511 #if 0
10512         void main(float4 in_position : POSITION, uint4 in_uint : UINT,
10513                 out float4 out_position : SV_POSITION, out uint out_uint : UINT,
10514                 out float3 out_float : FLOAT)
10515         {
10516             out_position = in_position;
10517             out_uint = in_uint.y;
10518             out_float = float3(1, 2, 3);
10519         }
10520 #endif
10521         0x43425844, 0x0521bc60, 0xd39733a4, 0x1522eea3, 0x0c741ea3, 0x00000001, 0x0000018c, 0x00000003,
10522         0x0000002c, 0x0000007c, 0x000000ec, 0x4e475349, 0x00000048, 0x00000002, 0x00000008, 0x00000038,
10523         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, 0x00000000, 0x00000000,
10524         0x00000001, 0x00000001, 0x0000020f, 0x49534f50, 0x4e4f4954, 0x4e495500, 0xabab0054, 0x4e47534f,
10525         0x00000068, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, 0x00000003, 0x00000000,
10526         0x0000000f, 0x0000005c, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000e01, 0x00000061,
10527         0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000807, 0x505f5653, 0x5449534f, 0x004e4f49,
10528         0x544e4955, 0x4f4c4600, 0xab005441, 0x58454853, 0x00000098, 0x00010050, 0x00000026, 0x0100086a,
10529         0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x00101022, 0x00000001, 0x04000067, 0x001020f2,
10530         0x00000000, 0x00000001, 0x03000065, 0x00102012, 0x00000001, 0x03000065, 0x00102072, 0x00000002,
10531         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x00102012, 0x00000001,
10532         0x0010101a, 0x00000001, 0x08000036, 0x00102072, 0x00000002, 0x00004002, 0x3f800000, 0x40000000,
10533         0x40400000, 0x00000000, 0x0100003e,
10534     };
10535     static const D3D12_SHADER_BYTECODE vs1 = {vs1_code, sizeof(vs1_code)};
10536     static const DWORD ps1_code[] =
10537     {
10538 #if 0
10539         void main(float4 position : SV_POSITION, uint in_uint : UINT,
10540                 float3 in_float : FLOAT, out float4 out_float : SV_TARGET0,
10541                 out uint4 out_uint : SV_TARGET1)
10542         {
10543             out_float.x = position.w;
10544             out_float.y = in_uint;
10545             out_float.z = in_float.z;
10546             out_float.w = 0;
10547             out_uint.x = 0xdeadbeef;
10548             out_uint.y = 0;
10549             out_uint.z = in_uint;
10550             out_uint.w = in_float.z;
10551         }
10552 #endif
10553         0x43425844, 0x762dbf5e, 0x2cc83972, 0x60c7aa48, 0xbca6118a, 0x00000001, 0x000001d4, 0x00000003,
10554         0x0000002c, 0x0000009c, 0x000000e8, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
10555         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000080f, 0x0000005c, 0x00000000, 0x00000000,
10556         0x00000001, 0x00000001, 0x00000101, 0x00000061, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
10557         0x00000407, 0x505f5653, 0x5449534f, 0x004e4f49, 0x544e4955, 0x4f4c4600, 0xab005441, 0x4e47534f,
10558         0x00000044, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
10559         0x0000000f, 0x00000038, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x0000000f, 0x545f5653,
10560         0x45475241, 0xabab0054, 0x52444853, 0x000000e4, 0x00000040, 0x00000039, 0x04002064, 0x00101082,
10561         0x00000000, 0x00000001, 0x03000862, 0x00101012, 0x00000001, 0x03001062, 0x00101042, 0x00000002,
10562         0x03000065, 0x001020f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000001, 0x05000056, 0x00102022,
10563         0x00000000, 0x0010100a, 0x00000001, 0x05000036, 0x00102012, 0x00000000, 0x0010103a, 0x00000000,
10564         0x05000036, 0x00102042, 0x00000000, 0x0010102a, 0x00000002, 0x05000036, 0x00102082, 0x00000000,
10565         0x00004001, 0x00000000, 0x0500001c, 0x00102082, 0x00000001, 0x0010102a, 0x00000002, 0x08000036,
10566         0x00102032, 0x00000001, 0x00004002, 0xdeadbeef, 0x00000000, 0x00000000, 0x00000000, 0x05000036,
10567         0x00102042, 0x00000001, 0x0010100a, 0x00000001, 0x0100003e,
10568     };
10569     static const D3D12_SHADER_BYTECODE ps1 = {ps1_code, sizeof(ps1_code)};
10570     static const DWORD vs2_code[] =
10571     {
10572 #if 0
10573         void main(float4 in_position : POSITION,
10574                 float4 in_texcoord0 : TEXCOORD0, float4 in_texcoord1 : TEXCOORD1,
10575                 float4 in_texcoord2 : TEXCOORD2,
10576                 out float4 position : Sv_Position,
10577                 out float2 texcoord0 : TEXCOORD0, out float2 texcoord1 : TEXCOORD1,
10578                 out float4 texcoord2 : TEXCOORD2, out float3 texcoord3 : TEXCOORD3)
10579         {
10580             position = in_position;
10581             texcoord0 = in_texcoord0.yx;
10582             texcoord1 = in_texcoord0.wz;
10583             texcoord2 = in_texcoord1;
10584             texcoord3 = in_texcoord2.yzx;
10585         }
10586 #endif
10587         0x43425844, 0x6721613b, 0xb997c7e4, 0x8bc3df4d, 0x813c93b9, 0x00000001, 0x00000224, 0x00000003,
10588         0x0000002c, 0x000000b0, 0x00000150, 0x4e475349, 0x0000007c, 0x00000004, 0x00000008, 0x00000068,
10589         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000071, 0x00000000, 0x00000000,
10590         0x00000003, 0x00000001, 0x00000f0f, 0x00000071, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
10591         0x00000f0f, 0x00000071, 0x00000002, 0x00000000, 0x00000003, 0x00000003, 0x0000070f, 0x49534f50,
10592         0x4e4f4954, 0x58455400, 0x524f4f43, 0xabab0044, 0x4e47534f, 0x00000098, 0x00000005, 0x00000008,
10593         0x00000080, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000008c, 0x00000000,
10594         0x00000000, 0x00000003, 0x00000001, 0x00000c03, 0x0000008c, 0x00000001, 0x00000000, 0x00000003,
10595         0x00000001, 0x0000030c, 0x0000008c, 0x00000002, 0x00000000, 0x00000003, 0x00000002, 0x0000000f,
10596         0x0000008c, 0x00000003, 0x00000000, 0x00000003, 0x00000003, 0x00000807, 0x505f7653, 0x7469736f,
10597         0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x52444853, 0x000000cc, 0x00010040, 0x00000033,
10598         0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x001010f2, 0x00000001, 0x0300005f, 0x001010f2,
10599         0x00000002, 0x0300005f, 0x00101072, 0x00000003, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
10600         0x03000065, 0x00102032, 0x00000001, 0x03000065, 0x001020c2, 0x00000001, 0x03000065, 0x001020f2,
10601         0x00000002, 0x03000065, 0x00102072, 0x00000003, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46,
10602         0x00000000, 0x05000036, 0x001020f2, 0x00000001, 0x00101b16, 0x00000001, 0x05000036, 0x001020f2,
10603         0x00000002, 0x00101e46, 0x00000002, 0x05000036, 0x00102072, 0x00000003, 0x00101496, 0x00000003,
10604         0x0100003e,
10605     };
10606     static const D3D12_SHADER_BYTECODE vs2 = {vs2_code, sizeof(vs2_code)};
10607     static const DWORD ps2_code[] =
10608     {
10609 #if 0
10610         void main(float4 position : Sv_Position,
10611                 float2 texcoord0 : TEXCOORD0, float2 texcoord1 : TEXCOORD1,
10612                 float4 texcoord2 : TEXCOORD2, float3 texcoord3 : TEXCOORD3,
10613                 out float4 target0 : Sv_Target0, out uint4 target1 : SV_Target1)
10614         {
10615             target0.x = texcoord0.x + texcoord0.y;
10616             target0.y = texcoord1.x;
10617             target0.z = texcoord3.z;
10618             target0.w = texcoord1.y;
10619 
10620             target1.x = texcoord2.x;
10621             target1.y = texcoord2.y;
10622             target1.w = texcoord2.w;
10623             target1.z = 0;
10624         }
10625 #endif
10626         0x43425844, 0xa6c0df60, 0x5bf34683, 0xa0093595, 0x98cca724, 0x00000001, 0x000001e8, 0x00000003,
10627         0x0000002c, 0x000000cc, 0x00000120, 0x4e475349, 0x00000098, 0x00000005, 0x00000008, 0x00000080,
10628         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000008c, 0x00000000, 0x00000000,
10629         0x00000003, 0x00000001, 0x00000303, 0x0000008c, 0x00000001, 0x00000000, 0x00000003, 0x00000001,
10630         0x00000c0c, 0x0000008c, 0x00000002, 0x00000000, 0x00000003, 0x00000002, 0x00000b0f, 0x0000008c,
10631         0x00000003, 0x00000000, 0x00000003, 0x00000003, 0x00000407, 0x505f7653, 0x7469736f, 0x006e6f69,
10632         0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
10633         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x00000042, 0x00000001, 0x00000000,
10634         0x00000001, 0x00000001, 0x0000000f, 0x545f7653, 0x65677261, 0x56530074, 0x7261545f, 0x00746567,
10635         0x52444853, 0x000000c0, 0x00000040, 0x00000030, 0x03001062, 0x00101032, 0x00000001, 0x03001062,
10636         0x001010c2, 0x00000001, 0x03001062, 0x001010b2, 0x00000002, 0x03001062, 0x00101042, 0x00000003,
10637         0x03000065, 0x001020f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000001, 0x07000000, 0x00102012,
10638         0x00000000, 0x0010101a, 0x00000001, 0x0010100a, 0x00000001, 0x05000036, 0x001020a2, 0x00000000,
10639         0x00101ea6, 0x00000001, 0x05000036, 0x00102042, 0x00000000, 0x0010102a, 0x00000003, 0x0500001c,
10640         0x001020b2, 0x00000001, 0x00101c46, 0x00000002, 0x05000036, 0x00102042, 0x00000001, 0x00004001,
10641         0x00000000, 0x0100003e,
10642     };
10643     static const D3D12_SHADER_BYTECODE ps2 = {ps2_code, sizeof(ps2_code)};
10644     static const DWORD ps3_code[] =
10645     {
10646 #if 0
10647         void main(float4 position : Sv_Position,
10648                 float2 texcoord0 : TEXCOORD0, float2 texcoord1 : TEXCOORD1,
10649                 float4 texcoord2 : TEXCOORD2, float3 texcoord3 : TEXCOORD3,
10650                 out float4 target0 : Sv_Target0, out uint4 target1 : SV_Target1)
10651         {
10652             target0.x = texcoord0.x;
10653             target0.y = texcoord1.y;
10654             target0.z = texcoord3.z;
10655             target0.w = texcoord3.z;
10656 
10657             target1.x = texcoord2.x;
10658             target1.y = 0;
10659             target1.w = texcoord2.w;
10660             target1.z = 0;
10661         }
10662 #endif
10663         0x43425844, 0x2df3a11d, 0x885fc859, 0x332d922b, 0xf8e01020, 0x00000001, 0x000001d8, 0x00000003,
10664         0x0000002c, 0x000000cc, 0x00000120, 0x4e475349, 0x00000098, 0x00000005, 0x00000008, 0x00000080,
10665         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000008c, 0x00000000, 0x00000000,
10666         0x00000003, 0x00000001, 0x00000103, 0x0000008c, 0x00000001, 0x00000000, 0x00000003, 0x00000001,
10667         0x0000080c, 0x0000008c, 0x00000002, 0x00000000, 0x00000003, 0x00000002, 0x0000090f, 0x0000008c,
10668         0x00000003, 0x00000000, 0x00000003, 0x00000003, 0x00000407, 0x505f7653, 0x7469736f, 0x006e6f69,
10669         0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
10670         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x00000042, 0x00000001, 0x00000000,
10671         0x00000001, 0x00000001, 0x0000000f, 0x545f7653, 0x65677261, 0x56530074, 0x7261545f, 0x00746567,
10672         0x52444853, 0x000000b0, 0x00000040, 0x0000002c, 0x03001062, 0x00101012, 0x00000001, 0x03001062,
10673         0x00101082, 0x00000001, 0x03001062, 0x00101092, 0x00000002, 0x03001062, 0x00101042, 0x00000003,
10674         0x03000065, 0x001020f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x00102032,
10675         0x00000000, 0x001010c6, 0x00000001, 0x05000036, 0x001020c2, 0x00000000, 0x00101aa6, 0x00000003,
10676         0x0500001c, 0x00102092, 0x00000001, 0x00101c06, 0x00000002, 0x08000036, 0x00102062, 0x00000001,
10677         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e,
10678     };
10679     static const D3D12_SHADER_BYTECODE ps3 = {ps3_code, sizeof(ps3_code)};
10680     /* position.xyw */
10681     static const DWORD ps4_code[] =
10682     {
10683 #if 0
10684         void main(float4 position : Sv_Position,
10685                 float2 texcoord0 : TEXCOORD0, float2 texcoord1 : TEXCOORD1,
10686                 float4 texcoord2 : TEXCOORD2, float3 texcoord3 : TEXCOORD3,
10687                 out float4 target0 : Sv_Target0, out uint4 target1 : SV_Target1)
10688         {
10689             if (all(position.xy < float2(64, 64)))
10690                 target0 = float4(0, 1, 0, 1);
10691             else
10692                 target0 = float4(0, 0, 0, 0);
10693 
10694             target1.xyzw = 0;
10695             target1.y = position.w;
10696         }
10697 #endif
10698         0x43425844, 0x6dac90a1, 0x518a6b0a, 0x393cc320, 0x5f6fbe5e, 0x00000001, 0x00000204, 0x00000003,
10699         0x0000002c, 0x000000cc, 0x00000120, 0x4e475349, 0x00000098, 0x00000005, 0x00000008, 0x00000080,
10700         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000b0f, 0x0000008c, 0x00000000, 0x00000000,
10701         0x00000003, 0x00000001, 0x00000003, 0x0000008c, 0x00000001, 0x00000000, 0x00000003, 0x00000001,
10702         0x0000000c, 0x0000008c, 0x00000002, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x0000008c,
10703         0x00000003, 0x00000000, 0x00000003, 0x00000003, 0x00000007, 0x505f7653, 0x7469736f, 0x006e6f69,
10704         0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
10705         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x00000042, 0x00000001, 0x00000000,
10706         0x00000001, 0x00000001, 0x0000000f, 0x545f7653, 0x65677261, 0x56530074, 0x7261545f, 0x00746567,
10707         0x52444853, 0x000000dc, 0x00000040, 0x00000037, 0x04002064, 0x001010b2, 0x00000000, 0x00000001,
10708         0x03000065, 0x001020f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000001, 0x02000068, 0x00000001,
10709         0x0a000031, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002, 0x42800000, 0x42800000,
10710         0x00000000, 0x00000000, 0x07000001, 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a,
10711         0x00000000, 0x0a000001, 0x001020f2, 0x00000000, 0x00100006, 0x00000000, 0x00004002, 0x00000000,
10712         0x3f800000, 0x00000000, 0x3f800000, 0x0500001c, 0x00102022, 0x00000001, 0x0010103a, 0x00000000,
10713         0x08000036, 0x001020d2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
10714         0x0100003e,
10715     };
10716     static const D3D12_SHADER_BYTECODE ps4 = {ps4_code, sizeof(ps4_code)};
10717 #if 0
10718     struct ps_data
10719     {
10720         float4 position : SV_Position;
10721         float4 color : COLOR;
10722         float3 color1 : COLOR1;
10723         float color2 : COLOR2;
10724     };
10725 
10726     ps_data vs_main(float4 position : POSITION)
10727     {
10728         ps_data o;
10729         o.position = position;
10730         o.color = float4(0, 1, 0, 1);
10731         o.color1 = (float3)0.5;
10732         o.color2 = 0.25;
10733         return o;
10734     }
10735 
10736     float4 ps_main(ps_data i) : SV_Target
10737     {
10738         return float4(i.color.rgb, i.color2);
10739     }
10740 #endif
10741     static const DWORD vs5_code[] =
10742     {
10743         0x43425844, 0xc3e1b9fc, 0xb99e43ef, 0x9a2a6dfc, 0xad719e68, 0x00000001, 0x00000190, 0x00000003,
10744         0x0000002c, 0x00000060, 0x000000e4, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
10745         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
10746         0x4e47534f, 0x0000007c, 0x00000004, 0x00000008, 0x00000068, 0x00000000, 0x00000001, 0x00000003,
10747         0x00000000, 0x0000000f, 0x00000074, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
10748         0x00000074, 0x00000001, 0x00000000, 0x00000003, 0x00000002, 0x00000807, 0x00000074, 0x00000002,
10749         0x00000000, 0x00000003, 0x00000002, 0x00000708, 0x505f5653, 0x7469736f, 0x006e6f69, 0x4f4c4f43,
10750         0xabab0052, 0x58454853, 0x000000a4, 0x00010050, 0x00000029, 0x0100086a, 0x0300005f, 0x001010f2,
10751         0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001,
10752         0x03000065, 0x00102072, 0x00000002, 0x03000065, 0x00102082, 0x00000002, 0x05000036, 0x001020f2,
10753         0x00000000, 0x00101e46, 0x00000000, 0x08000036, 0x001020f2, 0x00000001, 0x00004002, 0x00000000,
10754         0x3f800000, 0x00000000, 0x3f800000, 0x08000036, 0x001020f2, 0x00000002, 0x00004002, 0x3f000000,
10755         0x3f000000, 0x3f000000, 0x3e800000, 0x0100003e,
10756     };
10757     static const D3D12_SHADER_BYTECODE vs5 = {vs5_code, sizeof(vs5_code)};
10758     static const DWORD ps5_code[] =
10759     {
10760         0x43425844, 0x285bf397, 0xbc07e078, 0xc4e528e3, 0x74efea4d, 0x00000001, 0x00000148, 0x00000003,
10761         0x0000002c, 0x000000b0, 0x000000e4, 0x4e475349, 0x0000007c, 0x00000004, 0x00000008, 0x00000068,
10762         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000074, 0x00000000, 0x00000000,
10763         0x00000003, 0x00000001, 0x0000070f, 0x00000074, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
10764         0x00000007, 0x00000074, 0x00000002, 0x00000000, 0x00000003, 0x00000002, 0x00000808, 0x505f5653,
10765         0x7469736f, 0x006e6f69, 0x4f4c4f43, 0xabab0052, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008,
10766         0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261,
10767         0xabab0074, 0x58454853, 0x0000005c, 0x00000050, 0x00000017, 0x0100086a, 0x03001062, 0x00101072,
10768         0x00000001, 0x03001062, 0x00101082, 0x00000002, 0x03000065, 0x001020f2, 0x00000000, 0x05000036,
10769         0x00102072, 0x00000000, 0x00101246, 0x00000001, 0x05000036, 0x00102082, 0x00000000, 0x0010103a,
10770         0x00000002, 0x0100003e,
10771     };
10772     static const D3D12_SHADER_BYTECODE ps5 = {ps5_code, sizeof(ps5_code)};
10773     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
10774     {
10775         {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT,       0,  0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
10776         {"UINT",     0, DXGI_FORMAT_R32G32B32A32_UINT,  0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
10777         {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 32, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
10778         {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 48, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
10779         {"TEXCOORD", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 64, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
10780     };
10781     static const struct
10782     {
10783         struct vec4 position;
10784         struct uvec4 u;
10785         struct vec4 t0;
10786         struct vec4 t1;
10787         struct vec4 t2;
10788     }
10789     quad[] =
10790     {
10791         {{-1.0f, -1.0f}, {1, 2, 3, 4}, {3.0f, 3.0f, 8.0f, 4.0f}, {9.0f, 5.0f, 3.0f, 1.0f}, {7.0f, 2.0f, 5.0f}},
10792         {{-1.0f,  1.0f}, {1, 2, 3, 4}, {3.0f, 3.0f, 8.0f, 4.0f}, {9.0f, 5.0f, 3.0f, 1.0f}, {7.0f, 2.0f, 5.0f}},
10793         {{ 1.0f, -1.0f}, {1, 2, 3, 4}, {3.0f, 3.0f, 8.0f, 4.0f}, {9.0f, 5.0f, 3.0f, 1.0f}, {7.0f, 2.0f, 5.0f}},
10794         {{ 1.0f,  1.0f}, {1, 2, 3, 4}, {3.0f, 3.0f, 8.0f, 4.0f}, {9.0f, 5.0f, 3.0f, 1.0f}, {7.0f, 2.0f, 5.0f}},
10795     };
10796     static const struct
10797     {
10798         const D3D12_SHADER_BYTECODE *vs;
10799         const D3D12_SHADER_BYTECODE *ps;
10800         const struct vec4 expected_vec4;
10801         const struct uvec4 expected_uvec4;
10802     }
10803     tests[] =
10804     {
10805         {&vs1, &ps1, {1.0f, 2.0f, 3.0f, 0.00f}, {0xdeadbeef, 0, 2, 3}},
10806         {&vs2, &ps2, {6.0f, 4.0f, 7.0f, 8.00f}, {         9, 5, 0, 1}},
10807         {&vs2, &ps3, {3.0f, 8.0f, 7.0f, 7.00f}, {         9, 0, 0, 1}},
10808         {&vs2, &ps4, {0.0f, 1.0f, 0.0f, 1.00f}, {         0, 1, 0, 0}},
10809         {&vs5, &ps5, {0.0f, 1.0f, 0.0f, 0.25f}, {         0, 1, 0, 0}},
10810     };
10811 
10812     memset(&desc, 0, sizeof(desc));
10813     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
10814     desc.rt_descriptor_count = 2;
10815     desc.no_root_signature = true;
10816     if (!init_test_context(&context, &desc))
10817         return;
10818     command_list = context.list;
10819     queue = context.queue;
10820 
10821     context.root_signature = create_empty_root_signature(context.device,
10822             D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
10823 
10824     input_layout.pInputElementDescs = layout_desc;
10825     input_layout.NumElements = ARRAY_SIZE(layout_desc);
10826     init_pipeline_state_desc(&pso_desc, context.root_signature, desc.rt_format, NULL, NULL, &input_layout);
10827     pso_desc.NumRenderTargets = 2;
10828     pso_desc.RTVFormats[1] = DXGI_FORMAT_R32G32B32A32_UINT;
10829 
10830     rtvs[0] = context.rtv;
10831     rtvs[1] = get_cpu_rtv_handle(&context, context.rtv_heap, 1);
10832     desc.rt_format = pso_desc.RTVFormats[1];
10833     create_render_target(&context, &desc, &uint_render_target, &rtvs[1]);
10834 
10835     vb = create_upload_buffer(context.device, sizeof(quad), quad);
10836 
10837     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
10838     vbv.StrideInBytes = sizeof(*quad);
10839     vbv.SizeInBytes = sizeof(quad);
10840 
10841     for (i = 0; i < ARRAY_SIZE(tests); ++i)
10842     {
10843         vkd3d_test_set_context("Test %u", i);
10844 
10845         pso_desc.VS = *tests[i].vs;
10846         pso_desc.PS = *tests[i].ps;
10847         hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
10848                 &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
10849         ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
10850 
10851         if (i)
10852         {
10853             reset_command_list(command_list, context.allocator);
10854             transition_resource_state(command_list, context.render_target,
10855                     D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
10856             transition_resource_state(command_list, uint_render_target,
10857                     D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
10858         }
10859 
10860         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 2, &context.rtv, true, NULL);
10861         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
10862         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
10863         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
10864         ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
10865         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
10866         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
10867         ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
10868 
10869         transition_resource_state(command_list, context.render_target,
10870                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
10871         check_sub_resource_vec4(context.render_target, 0, queue, command_list, &tests[i].expected_vec4, 0);
10872         reset_command_list(command_list, context.allocator);
10873         transition_resource_state(command_list, uint_render_target,
10874                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
10875         check_sub_resource_uvec4(uint_render_target, 0, queue, command_list, &tests[i].expected_uvec4);
10876 
10877         ID3D12PipelineState_Release(context.pipeline_state);
10878         context.pipeline_state = NULL;
10879     }
10880     vkd3d_test_set_context(NULL);
10881 
10882     ID3D12Resource_Release(vb);
10883     ID3D12Resource_Release(uint_render_target);
10884     destroy_test_context(&context);
10885 }
10886 
check_descriptor_range_(unsigned int line,const D3D12_DESCRIPTOR_RANGE * range,const D3D12_DESCRIPTOR_RANGE * expected_range)10887 static void check_descriptor_range_(unsigned int line, const D3D12_DESCRIPTOR_RANGE *range,
10888         const D3D12_DESCRIPTOR_RANGE *expected_range)
10889 {
10890     ok_(line)(range->RangeType == expected_range->RangeType,
10891             "Got range type %#x, expected %#x.\n", range->RangeType, expected_range->RangeType);
10892     ok_(line)(range->NumDescriptors == expected_range->NumDescriptors,
10893             "Got descriptor count %u, expected %u.\n", range->NumDescriptors, expected_range->NumDescriptors);
10894     ok_(line)(range->BaseShaderRegister == expected_range->BaseShaderRegister,
10895             "Got base shader register %u, expected %u.\n",
10896             range->BaseShaderRegister, expected_range->BaseShaderRegister);
10897     ok_(line)(range->RegisterSpace == expected_range->RegisterSpace,
10898             "Got register space %u, expected %u.\n", range->RegisterSpace, expected_range->RegisterSpace);
10899     ok_(line)(range->OffsetInDescriptorsFromTableStart == expected_range->OffsetInDescriptorsFromTableStart,
10900             "Got offset %u, expected %u.\n", range->OffsetInDescriptorsFromTableStart,
10901             expected_range->OffsetInDescriptorsFromTableStart);
10902 }
10903 
check_descriptor_range1_(unsigned int line,const D3D12_DESCRIPTOR_RANGE1 * range,const D3D12_DESCRIPTOR_RANGE1 * expected_range,bool converted)10904 static void check_descriptor_range1_(unsigned int line, const D3D12_DESCRIPTOR_RANGE1 *range,
10905         const D3D12_DESCRIPTOR_RANGE1 *expected_range, bool converted)
10906 {
10907     unsigned int expected_flags = converted
10908             ? D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE | D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE
10909             : expected_range->Flags;
10910 
10911     ok_(line)(range->RangeType == expected_range->RangeType,
10912             "Got range type %#x, expected %#x.\n", range->RangeType, expected_range->RangeType);
10913     ok_(line)(range->NumDescriptors == expected_range->NumDescriptors,
10914             "Got descriptor count %u, expected %u.\n", range->NumDescriptors, expected_range->NumDescriptors);
10915     ok_(line)(range->BaseShaderRegister == expected_range->BaseShaderRegister,
10916             "Got base shader register %u, expected %u.\n",
10917             range->BaseShaderRegister, expected_range->BaseShaderRegister);
10918     ok_(line)(range->RegisterSpace == expected_range->RegisterSpace,
10919             "Got register space %u, expected %u.\n", range->RegisterSpace, expected_range->RegisterSpace);
10920     ok_(line)(range->Flags == expected_flags,
10921             "Got descriptor range flags %#x, expected %#x.\n", range->Flags, expected_flags);
10922     ok_(line)(range->OffsetInDescriptorsFromTableStart == expected_range->OffsetInDescriptorsFromTableStart,
10923             "Got offset %u, expected %u.\n", range->OffsetInDescriptorsFromTableStart,
10924             expected_range->OffsetInDescriptorsFromTableStart);
10925 }
10926 
check_root_parameter_(unsigned int line,const D3D12_ROOT_PARAMETER * parameter,const D3D12_ROOT_PARAMETER * expected_parameter)10927 static void check_root_parameter_(unsigned int line, const D3D12_ROOT_PARAMETER *parameter,
10928         const D3D12_ROOT_PARAMETER *expected_parameter)
10929 {
10930     const D3D12_ROOT_DESCRIPTOR *descriptor, *expected_descriptor;
10931     const D3D12_ROOT_DESCRIPTOR_TABLE *table, *expected_table;
10932     const D3D12_ROOT_CONSTANTS *constants, *expected_constants;
10933     unsigned int i;
10934 
10935     ok_(line)(parameter->ParameterType == expected_parameter->ParameterType,
10936             "Got type %#x, expected %#x.\n", parameter->ParameterType, expected_parameter->ParameterType);
10937     if (parameter->ParameterType != expected_parameter->ParameterType)
10938         return;
10939 
10940     switch (parameter->ParameterType)
10941     {
10942         case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
10943             table = &parameter->DescriptorTable;
10944             expected_table = &expected_parameter->DescriptorTable;
10945             ok_(line)(table->NumDescriptorRanges == expected_table->NumDescriptorRanges,
10946                     "Got range count %u, expected %u.\n",
10947                     table->NumDescriptorRanges, expected_table->NumDescriptorRanges);
10948             if (table->NumDescriptorRanges == expected_table->NumDescriptorRanges)
10949             {
10950                 for (i = 0; i < table->NumDescriptorRanges; ++i)
10951                     check_descriptor_range_(line, &table->pDescriptorRanges[i],
10952                             &expected_table->pDescriptorRanges[i]);
10953             }
10954             break;
10955         case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
10956             constants = &parameter->Constants;
10957             expected_constants = &expected_parameter->Constants;
10958             ok_(line)(constants->ShaderRegister == expected_constants->ShaderRegister,
10959                     "Got shader register %u, expected %u.\n",
10960                     constants->ShaderRegister, expected_constants->ShaderRegister);
10961             ok_(line)(constants->RegisterSpace == expected_constants->RegisterSpace,
10962                     "Got register space %u, expected %u.\n",
10963                     constants->RegisterSpace, expected_constants->RegisterSpace);
10964             ok_(line)(constants->Num32BitValues == expected_constants->Num32BitValues,
10965                     "Got 32-bit value count %u, expected %u.\n",
10966                     constants->Num32BitValues, expected_constants->Num32BitValues);
10967             break;
10968         case D3D12_ROOT_PARAMETER_TYPE_CBV:
10969         case D3D12_ROOT_PARAMETER_TYPE_SRV:
10970         case D3D12_ROOT_PARAMETER_TYPE_UAV:
10971             descriptor = &parameter->Descriptor;
10972             expected_descriptor = &expected_parameter->Descriptor;
10973             ok_(line)(descriptor->ShaderRegister == expected_descriptor->ShaderRegister,
10974                     "Got shader register %u, expected %u.\n",
10975                     descriptor->ShaderRegister, expected_descriptor->ShaderRegister);
10976             ok_(line)(descriptor->RegisterSpace == expected_descriptor->RegisterSpace,
10977                     "Got register space %u, expected %u.\n",
10978                     descriptor->RegisterSpace, expected_descriptor->RegisterSpace);
10979             break;
10980         default:
10981             trace("Unhandled type %#x.\n", parameter->ParameterType);
10982     }
10983 
10984     ok_(line)(parameter->ShaderVisibility == expected_parameter->ShaderVisibility,
10985             "Got shader visibility %#x, expected %#x.\n",
10986             parameter->ShaderVisibility, expected_parameter->ShaderVisibility);
10987 }
10988 
check_root_parameter1_(unsigned int line,const D3D12_ROOT_PARAMETER1 * parameter,const D3D12_ROOT_PARAMETER1 * expected_parameter,bool converted)10989 static void check_root_parameter1_(unsigned int line, const D3D12_ROOT_PARAMETER1 *parameter,
10990         const D3D12_ROOT_PARAMETER1 *expected_parameter, bool converted)
10991 {
10992     const D3D12_ROOT_DESCRIPTOR1 *descriptor, *expected_descriptor;
10993     const D3D12_ROOT_DESCRIPTOR_TABLE1 *table, *expected_table;
10994     const D3D12_ROOT_CONSTANTS *constants, *expected_constants;
10995     unsigned int expected_flags;
10996     unsigned int i;
10997 
10998     ok_(line)(parameter->ParameterType == expected_parameter->ParameterType,
10999             "Got type %#x, expected %#x.\n", parameter->ParameterType, expected_parameter->ParameterType);
11000     if (parameter->ParameterType != expected_parameter->ParameterType)
11001         return;
11002 
11003     switch (parameter->ParameterType)
11004     {
11005         case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
11006             table = &parameter->DescriptorTable;
11007             expected_table = &expected_parameter->DescriptorTable;
11008             ok_(line)(table->NumDescriptorRanges == expected_table->NumDescriptorRanges,
11009                     "Got range count %u, expected %u.\n",
11010                     table->NumDescriptorRanges, expected_table->NumDescriptorRanges);
11011             if (table->NumDescriptorRanges == expected_table->NumDescriptorRanges)
11012             {
11013                 for (i = 0; i < table->NumDescriptorRanges; ++i)
11014                     check_descriptor_range1_(line, &table->pDescriptorRanges[i],
11015                             &expected_table->pDescriptorRanges[i], converted);
11016             }
11017             break;
11018         case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
11019             constants = &parameter->Constants;
11020             expected_constants = &expected_parameter->Constants;
11021             ok_(line)(constants->ShaderRegister == expected_constants->ShaderRegister,
11022                     "Got shader register %u, expected %u.\n",
11023                     constants->ShaderRegister, expected_constants->ShaderRegister);
11024             ok_(line)(constants->RegisterSpace == expected_constants->RegisterSpace,
11025                     "Got register space %u, expected %u.\n",
11026                     constants->RegisterSpace, expected_constants->RegisterSpace);
11027             ok_(line)(constants->Num32BitValues == expected_constants->Num32BitValues,
11028                     "Got 32-bit value count %u, expected %u.\n",
11029                     constants->Num32BitValues, expected_constants->Num32BitValues);
11030             break;
11031         case D3D12_ROOT_PARAMETER_TYPE_CBV:
11032         case D3D12_ROOT_PARAMETER_TYPE_SRV:
11033         case D3D12_ROOT_PARAMETER_TYPE_UAV:
11034             descriptor = &parameter->Descriptor;
11035             expected_descriptor = &expected_parameter->Descriptor;
11036             ok_(line)(descriptor->ShaderRegister == expected_descriptor->ShaderRegister,
11037                     "Got shader register %u, expected %u.\n",
11038                     descriptor->ShaderRegister, expected_descriptor->ShaderRegister);
11039             ok_(line)(descriptor->RegisterSpace == expected_descriptor->RegisterSpace,
11040                     "Got register space %u, expected %u.\n",
11041                     descriptor->RegisterSpace, expected_descriptor->RegisterSpace);
11042             expected_flags = converted ? D3D12_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE : expected_descriptor->Flags;
11043             ok_(line)(descriptor->Flags == expected_flags,
11044                     "Got root descriptor flags %#x, expected %#x.\n",
11045                     descriptor->Flags, expected_flags);
11046             break;
11047         default:
11048             trace("Unhandled type %#x.\n", parameter->ParameterType);
11049     }
11050 
11051     ok_(line)(parameter->ShaderVisibility == expected_parameter->ShaderVisibility,
11052             "Got shader visibility %#x, expected %#x.\n",
11053             parameter->ShaderVisibility, expected_parameter->ShaderVisibility);
11054 }
11055 
check_static_sampler_(unsigned int line,const D3D12_STATIC_SAMPLER_DESC * sampler,const D3D12_STATIC_SAMPLER_DESC * expected_sampler)11056 static void check_static_sampler_(unsigned int line, const D3D12_STATIC_SAMPLER_DESC *sampler,
11057         const D3D12_STATIC_SAMPLER_DESC *expected_sampler)
11058 {
11059     ok_(line)(sampler->Filter == expected_sampler->Filter,
11060             "Got filter %#x, expected %#x.\n", sampler->Filter, expected_sampler->Filter);
11061     ok_(line)(sampler->AddressU == expected_sampler->AddressU,
11062             "Got address U %#x, expected %#x.\n", sampler->AddressU, expected_sampler->AddressU);
11063     ok_(line)(sampler->AddressV == expected_sampler->AddressV,
11064             "Got address V %#x, expected %#x.\n", sampler->AddressV, expected_sampler->AddressV);
11065     ok_(line)(sampler->AddressW == expected_sampler->AddressW,
11066             "Got address W %#x, expected %#x.\n", sampler->AddressW, expected_sampler->AddressW);
11067     ok_(line)(sampler->MipLODBias == expected_sampler->MipLODBias,
11068             "Got mip LOD bias %.8e, expected %.8e.\n", sampler->MipLODBias, expected_sampler->MipLODBias);
11069     ok_(line)(sampler->MaxAnisotropy == expected_sampler->MaxAnisotropy,
11070             "Got max anisotropy %u, expected %u.\n", sampler->MaxAnisotropy, expected_sampler->MaxAnisotropy);
11071     ok_(line)(sampler->ComparisonFunc == expected_sampler->ComparisonFunc,
11072             "Got comparison func %#x, expected %#x.\n", sampler->ComparisonFunc, expected_sampler->ComparisonFunc);
11073     ok_(line)(sampler->BorderColor == expected_sampler->BorderColor,
11074             "Got border color %#x, expected %#x.\n", sampler->BorderColor, expected_sampler->BorderColor);
11075     ok_(line)(sampler->MinLOD == expected_sampler->MinLOD,
11076             "Got min LOD %.8e, expected %.8e.\n", sampler->MinLOD, expected_sampler->MinLOD);
11077     ok_(line)(sampler->MaxLOD == expected_sampler->MaxLOD,
11078             "Got max LOD %.8e, expected %.8e.\n", sampler->MaxLOD, expected_sampler->MaxLOD);
11079     ok_(line)(sampler->ShaderRegister == expected_sampler->ShaderRegister,
11080             "Got shader register %u, expected %u.\n", sampler->ShaderRegister, expected_sampler->ShaderRegister);
11081     ok_(line)(sampler->RegisterSpace == expected_sampler->RegisterSpace,
11082             "Got register space %u, expected %u.\n", sampler->RegisterSpace, expected_sampler->RegisterSpace);
11083     ok_(line)(sampler->ShaderVisibility == expected_sampler->ShaderVisibility,
11084             "Got shader visibility %#x, expected %#x.\n",
11085             sampler->ShaderVisibility, expected_sampler->ShaderVisibility);
11086 }
11087 
11088 #define check_root_signature_desc(desc, expected) check_root_signature_desc_(__LINE__, desc, expected)
check_root_signature_desc_(unsigned int line,const D3D12_ROOT_SIGNATURE_DESC * desc,const D3D12_ROOT_SIGNATURE_DESC * expected_desc)11089 static void check_root_signature_desc_(unsigned int line, const D3D12_ROOT_SIGNATURE_DESC *desc,
11090         const D3D12_ROOT_SIGNATURE_DESC *expected_desc)
11091 {
11092     unsigned int i;
11093 
11094     ok_(line)(desc->NumParameters == expected_desc->NumParameters,
11095             "Got parameter count %u, expected %u.\n",
11096             desc->NumParameters, expected_desc->NumParameters);
11097     if (!expected_desc->pParameters)
11098     {
11099         ok_(line)(!desc->pParameters, "Got unexpected parameters %p.\n", desc->pParameters);
11100     }
11101     else if (desc->NumParameters == expected_desc->NumParameters)
11102     {
11103         for (i = 0; i < desc->NumParameters; ++i)
11104             check_root_parameter_(line, &desc->pParameters[i], &expected_desc->pParameters[i]);
11105     }
11106     ok_(line)(desc->NumStaticSamplers == expected_desc->NumStaticSamplers,
11107             "Got static sampler count %u, expected %u.\n",
11108             desc->NumStaticSamplers, expected_desc->NumStaticSamplers);
11109     if (!expected_desc->pStaticSamplers)
11110     {
11111         ok_(line)(!desc->pStaticSamplers, "Got unexpected static samplers %p.\n", desc->pStaticSamplers);
11112     }
11113     else if (desc->NumStaticSamplers == expected_desc->NumStaticSamplers)
11114     {
11115         for (i = 0; i < desc->NumStaticSamplers; ++i)
11116             check_static_sampler_(line, &desc->pStaticSamplers[i], &expected_desc->pStaticSamplers[i]);
11117     }
11118     ok_(line)(desc->Flags == expected_desc->Flags, "Got flags %#x, expected %#x.\n",
11119             desc->Flags, expected_desc->Flags);
11120 }
11121 
11122 #define check_root_signature_desc1(a, b, c) check_root_signature_desc1_(__LINE__, a, b, c)
check_root_signature_desc1_(unsigned int line,const D3D12_ROOT_SIGNATURE_DESC1 * desc,const D3D12_ROOT_SIGNATURE_DESC1 * expected_desc,bool converted)11123 static void check_root_signature_desc1_(unsigned int line, const D3D12_ROOT_SIGNATURE_DESC1 *desc,
11124         const D3D12_ROOT_SIGNATURE_DESC1 *expected_desc, bool converted)
11125 {
11126     unsigned int i;
11127 
11128     ok_(line)(desc->NumParameters == expected_desc->NumParameters,
11129             "Got parameter count %u, expected %u.\n",
11130             desc->NumParameters, expected_desc->NumParameters);
11131     if (!expected_desc->pParameters)
11132     {
11133         ok_(line)(!desc->pParameters, "Got unexpected parameters %p.\n", desc->pParameters);
11134     }
11135     else if (desc->NumParameters == expected_desc->NumParameters)
11136     {
11137         for (i = 0; i < desc->NumParameters; ++i)
11138             check_root_parameter1_(line, &desc->pParameters[i], &expected_desc->pParameters[i], converted);
11139     }
11140     ok_(line)(desc->NumStaticSamplers == expected_desc->NumStaticSamplers,
11141             "Got static sampler count %u, expected %u.\n",
11142             desc->NumStaticSamplers, expected_desc->NumStaticSamplers);
11143     if (!expected_desc->pStaticSamplers)
11144     {
11145         ok_(line)(!desc->pStaticSamplers, "Got unexpected static samplers %p.\n", desc->pStaticSamplers);
11146     }
11147     else if (desc->NumStaticSamplers == expected_desc->NumStaticSamplers)
11148     {
11149         for (i = 0; i < desc->NumStaticSamplers; ++i)
11150             check_static_sampler_(line, &desc->pStaticSamplers[i], &expected_desc->pStaticSamplers[i]);
11151     }
11152     ok_(line)(desc->Flags == expected_desc->Flags, "Got flags %#x, expected %#x.\n",
11153             desc->Flags, expected_desc->Flags);
11154 }
11155 
11156 #define check_root_signature_deserialization(a, b, c) check_root_signature_deserialization_(__LINE__, a, b, c)
check_root_signature_deserialization_(unsigned int line,const D3D12_SHADER_BYTECODE * code,const D3D12_ROOT_SIGNATURE_DESC * expected_desc,const D3D12_ROOT_SIGNATURE_DESC1 * expected_desc1)11157 static void check_root_signature_deserialization_(unsigned int line, const D3D12_SHADER_BYTECODE *code,
11158         const D3D12_ROOT_SIGNATURE_DESC *expected_desc, const D3D12_ROOT_SIGNATURE_DESC1 *expected_desc1)
11159 {
11160     const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *versioned_desc, *versioned_desc2;
11161     ID3D12VersionedRootSignatureDeserializer *versioned_deserializer;
11162     ID3D12RootSignatureDeserializer *deserializer;
11163     const D3D12_ROOT_SIGNATURE_DESC *desc;
11164     ULONG refcount;
11165     HRESULT hr;
11166 
11167     if (!code->BytecodeLength)
11168         return;
11169 
11170     hr = D3D12CreateRootSignatureDeserializer(code->pShaderBytecode, code->BytecodeLength,
11171             &IID_ID3D12RootSignatureDeserializer, (void **)&deserializer);
11172     ok_(line)(hr == S_OK, "Failed to create deserializer, hr %#x.\n", hr);
11173 
11174     desc = ID3D12RootSignatureDeserializer_GetRootSignatureDesc(deserializer);
11175     ok(desc, "Got NULL root signature desc.\n");
11176     check_root_signature_desc_(line, desc, expected_desc);
11177 
11178     refcount = ID3D12RootSignatureDeserializer_Release(deserializer);
11179     ok_(line)(!refcount, "ID3D12RootSignatureDeserializer has %u references left.\n", (unsigned int)refcount);
11180 
11181     if (!pfn_D3D12CreateVersionedRootSignatureDeserializer)
11182         return;
11183 
11184     hr = pfn_D3D12CreateVersionedRootSignatureDeserializer(code->pShaderBytecode, code->BytecodeLength,
11185             &IID_ID3D12VersionedRootSignatureDeserializer, (void **)&versioned_deserializer);
11186     ok_(line)(hr == S_OK, "Failed to create versioned deserializer, hr %#x.\n", hr);
11187 
11188     versioned_desc = ID3D12VersionedRootSignatureDeserializer_GetUnconvertedRootSignatureDesc(versioned_deserializer);
11189     ok(versioned_desc, "Got NULL root signature desc.\n");
11190     ok(versioned_desc->Version == D3D_ROOT_SIGNATURE_VERSION_1_0, "Got unexpected version %#x.\n", versioned_desc->Version);
11191     check_root_signature_desc_(line, &versioned_desc->Desc_1_0, expected_desc);
11192 
11193     hr = ID3D12VersionedRootSignatureDeserializer_GetRootSignatureDescAtVersion(versioned_deserializer,
11194             D3D_ROOT_SIGNATURE_VERSION_1_0, &versioned_desc2);
11195     ok_(line)(hr == S_OK, "Failed to get root signature 1.0, hr %#x.\n", hr);
11196     ok_(line)(versioned_desc2 == versioned_desc, "Got unexpected pointer %p.\n", versioned_desc2);
11197 
11198     hr = ID3D12VersionedRootSignatureDeserializer_GetRootSignatureDescAtVersion(versioned_deserializer,
11199             D3D_ROOT_SIGNATURE_VERSION_1_1, &versioned_desc);
11200     ok_(line)(hr == S_OK, "Failed to get root signature 1.0, hr %#x.\n", hr);
11201     ok(versioned_desc, "Got NULL root signature desc.\n");
11202     ok(versioned_desc->Version == D3D_ROOT_SIGNATURE_VERSION_1_1, "Got unexpected version %#x.\n", versioned_desc->Version);
11203     check_root_signature_desc1_(line, &versioned_desc->Desc_1_1, expected_desc1, true);
11204 
11205     refcount = ID3D12VersionedRootSignatureDeserializer_Release(versioned_deserializer);
11206     ok_(line)(!refcount, "ID3D12VersionedRootSignatureDeserializer has %u references left.\n", (unsigned int)refcount);
11207 }
11208 
11209 #define check_root_signature_deserialization1(a, b, c) check_root_signature_deserialization1_(__LINE__, a, b, c)
check_root_signature_deserialization1_(unsigned int line,const D3D12_SHADER_BYTECODE * code,const D3D12_ROOT_SIGNATURE_DESC * expected_desc,const D3D12_ROOT_SIGNATURE_DESC1 * expected_desc1)11210 static void check_root_signature_deserialization1_(unsigned int line, const D3D12_SHADER_BYTECODE *code,
11211         const D3D12_ROOT_SIGNATURE_DESC *expected_desc, const D3D12_ROOT_SIGNATURE_DESC1 *expected_desc1)
11212 {
11213     const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *versioned_desc, *versioned_desc2;
11214     ID3D12VersionedRootSignatureDeserializer *versioned_deserializer;
11215     ID3D12RootSignatureDeserializer *deserializer;
11216     const D3D12_ROOT_SIGNATURE_DESC *desc;
11217     ULONG refcount;
11218     HRESULT hr;
11219 
11220     hr = pfn_D3D12CreateVersionedRootSignatureDeserializer(code->pShaderBytecode, code->BytecodeLength,
11221             &IID_ID3D12VersionedRootSignatureDeserializer, (void **)&versioned_deserializer);
11222     ok_(line)(hr == S_OK, "Failed to create deserializer, hr %#x.\n", hr);
11223 
11224     versioned_desc = ID3D12VersionedRootSignatureDeserializer_GetUnconvertedRootSignatureDesc(versioned_deserializer);
11225     ok(versioned_desc, "Got NULL root signature desc.\n");
11226     ok(versioned_desc->Version == D3D_ROOT_SIGNATURE_VERSION_1_1, "Got unexpected version %#x.\n", versioned_desc->Version);
11227     check_root_signature_desc1_(line, &versioned_desc->Desc_1_1, expected_desc1, false);
11228 
11229     hr = ID3D12VersionedRootSignatureDeserializer_GetRootSignatureDescAtVersion(versioned_deserializer,
11230             D3D_ROOT_SIGNATURE_VERSION_1_1, &versioned_desc2);
11231     ok_(line)(hr == S_OK, "Failed to get root signature 1.1, hr %#x.\n", hr);
11232     ok_(line)(versioned_desc2 == versioned_desc, "Got unexpected pointer %p.\n", versioned_desc2);
11233 
11234     hr = ID3D12VersionedRootSignatureDeserializer_GetRootSignatureDescAtVersion(versioned_deserializer,
11235             D3D_ROOT_SIGNATURE_VERSION_1_0, &versioned_desc);
11236     ok_(line)(hr == S_OK, "Failed to get root signature 1.0, hr %#x.\n", hr);
11237     ok(versioned_desc, "Got NULL root signature desc.\n");
11238     ok(versioned_desc->Version == D3D_ROOT_SIGNATURE_VERSION_1_0, "Got unexpected version %#x.\n", versioned_desc->Version);
11239     check_root_signature_desc_(line, &versioned_desc->Desc_1_0, expected_desc);
11240 
11241     refcount = ID3D12VersionedRootSignatureDeserializer_Release(versioned_deserializer);
11242     ok_(line)(!refcount, "ID3D12VersionedRootSignatureDeserializer has %u references left.\n", (unsigned int)refcount);
11243 
11244     hr = D3D12CreateRootSignatureDeserializer(code->pShaderBytecode, code->BytecodeLength,
11245             &IID_ID3D12RootSignatureDeserializer, (void **)&deserializer);
11246     ok_(line)(hr == S_OK, "Failed to create deserializer, hr %#x.\n", hr);
11247 
11248     desc = ID3D12RootSignatureDeserializer_GetRootSignatureDesc(deserializer);
11249     ok(desc, "Got NULL root signature desc.\n");
11250     check_root_signature_desc_(line, desc, expected_desc);
11251 
11252     refcount = ID3D12RootSignatureDeserializer_Release(deserializer);
11253     ok_(line)(!refcount, "ID3D12RootSignatureDeserializer has %u references left.\n", (unsigned int)refcount);
11254 }
11255 
11256 #define check_root_signature_serialization(a, b) check_root_signature_serialization_(__LINE__, a, b)
check_root_signature_serialization_(unsigned int line,const D3D12_SHADER_BYTECODE * bytecode,const D3D12_ROOT_SIGNATURE_DESC * desc)11257 static void check_root_signature_serialization_(unsigned int line, const D3D12_SHADER_BYTECODE *bytecode,
11258         const D3D12_ROOT_SIGNATURE_DESC *desc)
11259 {
11260     const DWORD *code = bytecode->pShaderBytecode;
11261     ID3DBlob *blob, *error_blob;
11262     DWORD *blob_buffer;
11263     size_t blob_size;
11264     unsigned int i;
11265     HRESULT hr;
11266 
11267     if (!bytecode->BytecodeLength)
11268         return;
11269 
11270     error_blob = (ID3DBlob *)0xdeadbeef;
11271     hr = D3D12SerializeRootSignature(desc, D3D_ROOT_SIGNATURE_VERSION_1_0, &blob, &error_blob);
11272     ok_(line)(hr == S_OK, "Failed to serialize root signature, hr %#x.\n", hr);
11273     ok_(line)(!error_blob, "Got unexpected error blob %p.\n", error_blob);
11274 
11275     blob_buffer = ID3D10Blob_GetBufferPointer(blob);
11276     blob_size = ID3D10Blob_GetBufferSize(blob);
11277     ok_(line)(blob_size == bytecode->BytecodeLength, "Got size %u, expected %u.\n",
11278             (unsigned int)blob_size, (unsigned int)bytecode->BytecodeLength);
11279 
11280     for (i = 0; i < bytecode->BytecodeLength / sizeof(*code); ++i)
11281     {
11282         ok_(line)(blob_buffer[i] == code[i], "Got dword %#x, expected %#x at %u.\n",
11283                 (unsigned int)blob_buffer[i], (unsigned int)code[i], i);
11284     }
11285 
11286     ID3D10Blob_Release(blob);
11287 }
11288 
11289 #define check_root_signature_serialization1(a, b) check_root_signature_serialization1_(__LINE__, a, b)
check_root_signature_serialization1_(unsigned int line,const D3D12_SHADER_BYTECODE * bytecode,const D3D12_ROOT_SIGNATURE_DESC1 * desc)11290 static void check_root_signature_serialization1_(unsigned int line, const D3D12_SHADER_BYTECODE *bytecode,
11291         const D3D12_ROOT_SIGNATURE_DESC1 *desc)
11292 {
11293     D3D12_VERSIONED_ROOT_SIGNATURE_DESC versioned_desc;
11294     const DWORD *code = bytecode->pShaderBytecode;
11295     ID3DBlob *blob, *error_blob;
11296     DWORD *blob_buffer;
11297     size_t blob_size;
11298     unsigned int i;
11299     HRESULT hr;
11300 
11301     versioned_desc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1;
11302     versioned_desc.Desc_1_1 = *desc;
11303 
11304     error_blob = (ID3DBlob *)0xdeadbeef;
11305     hr = pfn_D3D12SerializeVersionedRootSignature(&versioned_desc, &blob, &error_blob);
11306     ok_(line)(hr == S_OK, "Failed to serialize root signature, hr %#x.\n", hr);
11307     ok_(line)(!error_blob, "Got unexpected error blob %p.\n", error_blob);
11308 
11309     blob_buffer = ID3D10Blob_GetBufferPointer(blob);
11310     blob_size = ID3D10Blob_GetBufferSize(blob);
11311     ok_(line)(blob_size == bytecode->BytecodeLength, "Got size %u, expected %u.\n",
11312             (unsigned int)blob_size, (unsigned int)bytecode->BytecodeLength);
11313 
11314     for (i = 0; i < bytecode->BytecodeLength / sizeof(*code); ++i)
11315     {
11316         ok_(line)(blob_buffer[i] == code[i], "Got dword %#x, expected %#x at %u.\n",
11317                 (unsigned int)blob_buffer[i], (unsigned int)code[i], i);
11318     }
11319 
11320     ID3D10Blob_Release(blob);
11321 }
11322 
test_root_signature_byte_code(void)11323 static void test_root_signature_byte_code(void)
11324 {
11325     ID3D12VersionedRootSignatureDeserializer *versioned_deserializer;
11326     ID3D12RootSignatureDeserializer *deserializer;
11327     ID3DBlob *blob;
11328     unsigned int i;
11329     ULONG refcount;
11330     HRESULT hr;
11331 
11332 #if 0
11333     #define RS ""
11334 #endif
11335     /* /T rootsig_1_0 /E RS */
11336     static const DWORD empty_rootsig[] =
11337     {
11338         0x43425844, 0xd64afc1d, 0x5dc27735, 0x9edacb4a, 0x6bd8a7fa, 0x00000001, 0x00000044, 0x00000001,
11339         0x00000024, 0x30535452, 0x00000018, 0x00000001, 0x00000000, 0x00000018, 0x00000000, 0x00000018,
11340         0x00000000,
11341     };
11342     /* /T rootsig_1_1 /E RS */
11343     static const DWORD empty_rootsig1[] =
11344     {
11345         0x43425844, 0x791882cb, 0x83c1db39, 0x327edc93, 0x3163085b, 0x00000001, 0x00000044, 0x00000001,
11346         0x00000024, 0x30535452, 0x00000018, 0x00000002, 0x00000000, 0x00000018, 0x00000000, 0x00000018,
11347         0x00000000,
11348     };
11349     static const D3D12_ROOT_SIGNATURE_DESC empty_rootsig_desc =
11350     {
11351         .Flags = 0,
11352     };
11353     static const D3D12_ROOT_SIGNATURE_DESC1 empty_rootsig_desc1 =
11354     {
11355         .Flags = 0,
11356     };
11357 
11358 #if 0
11359     #define RS "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT)"
11360 #endif
11361     static const DWORD ia_rootsig[] =
11362     {
11363         0x43425844, 0x05bbd62e, 0xc74d3646, 0xde1407a5, 0x0d99273d, 0x00000001, 0x00000044, 0x00000001,
11364         0x00000024, 0x30535452, 0x00000018, 0x00000001, 0x00000000, 0x00000018, 0x00000000, 0x00000018,
11365         0x00000001,
11366     };
11367     static const DWORD ia_rootsig1[] =
11368     {
11369         0x43425844, 0x1e922238, 0xa7743a59, 0x652c0188, 0xe999b061, 0x00000001, 0x00000044, 0x00000001,
11370         0x00000024, 0x30535452, 0x00000018, 0x00000002, 0x00000000, 0x00000018, 0x00000000, 0x00000018,
11371         0x00000001,
11372     };
11373     static const D3D12_ROOT_SIGNATURE_DESC ia_rootsig_desc =
11374     {
11375         .Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT,
11376     };
11377     static const D3D12_ROOT_SIGNATURE_DESC1 ia_rootsig_desc1 =
11378     {
11379         .Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT,
11380     };
11381 
11382 #if 0
11383     #define RS "RootFlags(DENY_PIXEL_SHADER_ROOT_ACCESS)"
11384 #endif
11385     static const DWORD deny_ps_rootsig[] =
11386     {
11387         0x43425844, 0xfad3a4ce, 0xf246286e, 0xeaa9e176, 0x278d5137, 0x00000001, 0x00000044, 0x00000001,
11388         0x00000024, 0x30535452, 0x00000018, 0x00000001, 0x00000000, 0x00000018, 0x00000000, 0x00000018,
11389         0x00000020,
11390     };
11391     static const DWORD deny_ps_rootsig1[] =
11392     {
11393         0x43425844, 0xca541ae8, 0x791dbcaa, 0xe8a61219, 0x697a84c7, 0x00000001, 0x00000044, 0x00000001,
11394         0x00000024, 0x30535452, 0x00000018, 0x00000002, 0x00000000, 0x00000018, 0x00000000, 0x00000018,
11395         0x00000020,
11396     };
11397     static const D3D12_ROOT_SIGNATURE_DESC deny_ps_rootsig_desc =
11398     {
11399         .Flags = D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS,
11400     };
11401     static const D3D12_ROOT_SIGNATURE_DESC1 deny_ps_rootsig_desc1 =
11402     {
11403         .Flags = D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS,
11404     };
11405 
11406 #if 0
11407     #define RS "CBV(b3, space = 0)"
11408 #endif
11409     static const DWORD cbv_rootsig[] =
11410     {
11411         0x43425844, 0x8dc5087e, 0x5cb9bf0d, 0x2e465ae3, 0x6291e0e0, 0x00000001, 0x00000058, 0x00000001,
11412         0x00000024, 0x30535452, 0x0000002c, 0x00000001, 0x00000001, 0x00000018, 0x00000000, 0x0000002c,
11413         0x00000000, 0x00000002, 0x00000000, 0x00000024, 0x00000003, 0x00000000,
11414 
11415     };
11416     static const DWORD cbv_rootsig1[] =
11417     {
11418         0x43425844, 0x66f3e4ad, 0x9938583c, 0x4eaf4733, 0x7940ab73, 0x00000001, 0x0000005c, 0x00000001,
11419         0x00000024, 0x30535452, 0x00000030, 0x00000002, 0x00000001, 0x00000018, 0x00000000, 0x00000030,
11420         0x00000000, 0x00000002, 0x00000000, 0x00000024, 0x00000003, 0x00000000, 0x00000000,
11421     };
11422     static const D3D12_ROOT_PARAMETER cbv_parameters[] =
11423     {
11424         {D3D12_ROOT_PARAMETER_TYPE_CBV, .Descriptor = {3, 0}},
11425     };
11426     static const D3D12_ROOT_SIGNATURE_DESC cbv_rootsig_desc =
11427     {
11428         .NumParameters = ARRAY_SIZE(cbv_parameters),
11429         .pParameters = cbv_parameters,
11430     };
11431     static const D3D12_ROOT_PARAMETER1 cbv_parameters1[] =
11432     {
11433         {D3D12_ROOT_PARAMETER_TYPE_CBV, .Descriptor = {3, 0}},
11434     };
11435     static const D3D12_ROOT_SIGNATURE_DESC1 cbv_rootsig_desc1 =
11436     {
11437         .NumParameters = ARRAY_SIZE(cbv_parameters1),
11438         .pParameters = cbv_parameters1,
11439     };
11440 
11441 #if 0
11442     #define RS "CBV(b4, space = 1, visibility = SHADER_VISIBILITY_GEOMETRY)"
11443 #endif
11444     static const DWORD cbv2_rootsig[] =
11445     {
11446         0x43425844, 0x6d4cfb48, 0xbfecaa8d, 0x379ff9c3, 0x0cc56997, 0x00000001, 0x00000058, 0x00000001,
11447         0x00000024, 0x30535452, 0x0000002c, 0x00000001, 0x00000001, 0x00000018, 0x00000000, 0x0000002c,
11448         0x00000000, 0x00000002, 0x00000004, 0x00000024, 0x00000004, 0x00000001,
11449     };
11450     static DWORD cbv2_rootsig1[] =
11451     {
11452         0x43425844, 0x8450397e, 0x4e136d61, 0xb4fe3b44, 0xc7223872, 0x00000001, 0x0000005c, 0x00000001,
11453         0x00000024, 0x30535452, 0x00000030, 0x00000002, 0x00000001, 0x00000018, 0x00000000, 0x00000030,
11454         0x00000000, 0x00000002, 0x00000004, 0x00000024, 0x00000004, 0x00000001, 0x00000000,
11455     };
11456     static const D3D12_ROOT_PARAMETER cbv2_parameters[] =
11457     {
11458         {D3D12_ROOT_PARAMETER_TYPE_CBV, .Descriptor = {4, 1}, D3D12_SHADER_VISIBILITY_GEOMETRY},
11459     };
11460     static const D3D12_ROOT_SIGNATURE_DESC cbv2_rootsig_desc =
11461     {
11462         .NumParameters = ARRAY_SIZE(cbv2_parameters),
11463         .pParameters = cbv2_parameters,
11464     };
11465     static const D3D12_ROOT_PARAMETER1 cbv2_parameters1[] =
11466     {
11467         {D3D12_ROOT_PARAMETER_TYPE_CBV, .Descriptor = {4, 1}, D3D12_SHADER_VISIBILITY_GEOMETRY},
11468     };
11469     static const D3D12_ROOT_SIGNATURE_DESC1 cbv2_rootsig_desc1 =
11470     {
11471         .NumParameters = ARRAY_SIZE(cbv2_parameters1),
11472         .pParameters = cbv2_parameters1,
11473     };
11474 
11475 #if 0
11476     #define RS "RootFlags(DENY_VERTEX_SHADER_ROOT_ACCESS), SRV(t13)"
11477 #endif
11478     static const DWORD srv_rootsig[] =
11479     {
11480         0x43425844, 0xbc00e5e0, 0xffff2fd3, 0x85c2d405, 0xa61db5e5, 0x00000001, 0x00000058, 0x00000001,
11481         0x00000024, 0x30535452, 0x0000002c, 0x00000001, 0x00000001, 0x00000018, 0x00000000, 0x0000002c,
11482         0x00000002, 0x00000003, 0x00000000, 0x00000024, 0x0000000d, 0x00000000,
11483     };
11484     static const DWORD srv_rootsig1[] =
11485     {
11486         0x43425844, 0xe79f4ac0, 0x1ac0829e, 0x94fddf9d, 0xd83d8bbf, 0x00000001, 0x0000005c, 0x00000001,
11487         0x00000024, 0x30535452, 0x00000030, 0x00000002, 0x00000001, 0x00000018, 0x00000000, 0x00000030,
11488         0x00000002, 0x00000003, 0x00000000, 0x00000024, 0x0000000d, 0x00000000, 0x00000000,
11489     };
11490     static const D3D12_ROOT_PARAMETER srv_parameters[] =
11491     {
11492         {D3D12_ROOT_PARAMETER_TYPE_SRV, .Descriptor = {13}},
11493     };
11494     static const D3D12_ROOT_SIGNATURE_DESC srv_rootsig_desc =
11495     {
11496         .NumParameters = ARRAY_SIZE(srv_parameters),
11497         .pParameters = srv_parameters,
11498         .Flags = D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS,
11499     };
11500     static const D3D12_ROOT_PARAMETER1 srv_parameters1[] =
11501     {
11502         {D3D12_ROOT_PARAMETER_TYPE_SRV, .Descriptor = {13}},
11503     };
11504     static const D3D12_ROOT_SIGNATURE_DESC1 srv_rootsig_desc1 =
11505     {
11506         .NumParameters = ARRAY_SIZE(srv_parameters1),
11507         .pParameters = srv_parameters1,
11508         .Flags = D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS,
11509     };
11510 
11511 #if 0
11512     #define RS "UAV(u6)"
11513 #endif
11514     static const DWORD uav_rootsig[] =
11515     {
11516         0x43425844, 0xf873c52c, 0x69f5cbea, 0xaf6bc9f4, 0x2ccf8b54, 0x00000001, 0x00000058, 0x00000001,
11517         0x00000024, 0x30535452, 0x0000002c, 0x00000001, 0x00000001, 0x00000018, 0x00000000, 0x0000002c,
11518         0x00000000, 0x00000004, 0x00000000, 0x00000024, 0x00000006, 0x00000000,
11519     };
11520     static const DWORD uav_rootsig1[] =
11521     {
11522         0x43425844, 0xbd670c62, 0x5c35651b, 0xfb9b9bd1, 0x8a4dddde, 0x00000001, 0x0000005c, 0x00000001,
11523         0x00000024, 0x30535452, 0x00000030, 0x00000002, 0x00000001, 0x00000018, 0x00000000, 0x00000030,
11524         0x00000000, 0x00000004, 0x00000000, 0x00000024, 0x00000006, 0x00000000, 0x00000000,
11525     };
11526     static const D3D12_ROOT_PARAMETER uav_parameters[] =
11527     {
11528         {D3D12_ROOT_PARAMETER_TYPE_UAV, .Descriptor = {6}},
11529     };
11530     static const D3D12_ROOT_SIGNATURE_DESC uav_rootsig_desc =
11531     {
11532         .NumParameters = ARRAY_SIZE(uav_parameters),
11533         .pParameters = uav_parameters,
11534     };
11535     static const D3D12_ROOT_PARAMETER1 uav_parameters1[] =
11536     {
11537         {D3D12_ROOT_PARAMETER_TYPE_UAV, .Descriptor = {6}},
11538     };
11539     static const D3D12_ROOT_SIGNATURE_DESC1 uav_rootsig_desc1 =
11540     {
11541         .NumParameters = ARRAY_SIZE(uav_parameters1),
11542         .pParameters = uav_parameters1,
11543     };
11544 
11545 #if 0
11546     #define RS "CBV(b4, space = 1, visibility = SHADER_VISIBILITY_VERTEX), " \
11547             "SRV(t13, flags = DATA_STATIC), " \
11548             "UAV(u6, flags = DATA_STATIC_WHILE_SET_AT_EXECUTE)"
11549 #endif
11550     static const DWORD root_descriptors_rootsig1[] =
11551     {
11552         0x43425844, 0x8ddedbbe, 0xbcfea259, 0x6b35bfbb, 0x23e1de24, 0x00000001, 0x0000008c, 0x00000001,
11553         0x00000024, 0x30535452, 0x00000060, 0x00000002, 0x00000003, 0x00000018, 0x00000000, 0x00000060,
11554         0x00000000, 0x00000002, 0x00000001, 0x0000003c, 0x00000003, 0x00000000, 0x00000048, 0x00000004,
11555         0x00000000, 0x00000054, 0x00000004, 0x00000001, 0x00000000, 0x0000000d, 0x00000000, 0x00000008,
11556         0x00000006, 0x00000000, 0x00000004,
11557     };
11558     static const D3D12_ROOT_PARAMETER root_descriptors_parameters[] =
11559     {
11560         {D3D12_ROOT_PARAMETER_TYPE_CBV, .Descriptor = {4, 1}, D3D12_SHADER_VISIBILITY_VERTEX},
11561         {D3D12_ROOT_PARAMETER_TYPE_SRV, .Descriptor = {13}},
11562         {D3D12_ROOT_PARAMETER_TYPE_UAV, .Descriptor = {6}},
11563     };
11564     static const D3D12_ROOT_SIGNATURE_DESC root_descriptors_desc =
11565     {
11566         .NumParameters = ARRAY_SIZE(root_descriptors_parameters),
11567         .pParameters = root_descriptors_parameters,
11568     };
11569     static const D3D12_ROOT_PARAMETER1 root_descriptors_parameters1[] =
11570     {
11571         {D3D12_ROOT_PARAMETER_TYPE_CBV, .Descriptor = {4, 1}, D3D12_SHADER_VISIBILITY_VERTEX},
11572         {D3D12_ROOT_PARAMETER_TYPE_SRV, .Descriptor = {13, 0, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC}},
11573         {D3D12_ROOT_PARAMETER_TYPE_UAV, .Descriptor = {6, 0, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE}},
11574     };
11575     static const D3D12_ROOT_SIGNATURE_DESC1 root_descriptors_desc1 =
11576     {
11577         .NumParameters = ARRAY_SIZE(root_descriptors_parameters1),
11578         .pParameters = root_descriptors_parameters1,
11579     };
11580 
11581 #if 0
11582     #define RS "RootConstants(num32BitConstants=3, b4), " \
11583             "RootConstants(num32BitConstants=4, b5, space = 3)"
11584 #endif
11585     static const DWORD constants_rootsig[] =
11586     {
11587         0x43425844, 0xbc015590, 0xa9a4a345, 0x7e446850, 0x2be05281, 0x00000001, 0x00000074, 0x00000001,
11588         0x00000024, 0x30535452, 0x00000048, 0x00000001, 0x00000002, 0x00000018, 0x00000000, 0x00000048,
11589         0x00000000, 0x00000001, 0x00000000, 0x00000030, 0x00000001, 0x00000000, 0x0000003c, 0x00000004,
11590         0x00000000, 0x00000003, 0x00000005, 0x00000003, 0x00000004,
11591     };
11592     static const DWORD constants_rootsig1[] =
11593     {
11594         0x43425844, 0xaa6e3eb1, 0x092b0bd3, 0x63af9657, 0xa97a0fe4, 0x00000001, 0x00000074, 0x00000001,
11595         0x00000024, 0x30535452, 0x00000048, 0x00000002, 0x00000002, 0x00000018, 0x00000000, 0x00000048,
11596         0x00000000, 0x00000001, 0x00000000, 0x00000030, 0x00000001, 0x00000000, 0x0000003c, 0x00000004,
11597         0x00000000, 0x00000003, 0x00000005, 0x00000003, 0x00000004,
11598     };
11599     static const D3D12_ROOT_PARAMETER constants_parameters[] =
11600     {
11601         {D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, .Constants = {4, 0, 3}},
11602         {D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, .Constants = {5, 3, 4}},
11603     };
11604     static const D3D12_ROOT_SIGNATURE_DESC constants_rootsig_desc =
11605     {
11606         .NumParameters = ARRAY_SIZE(constants_parameters),
11607         .pParameters = constants_parameters,
11608     };
11609     static const D3D12_ROOT_PARAMETER1 constants_parameters1[] =
11610     {
11611         {D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, .Constants = {4, 0, 3}},
11612         {D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, .Constants = {5, 3, 4}},
11613     };
11614     static const D3D12_ROOT_SIGNATURE_DESC1 constants_rootsig_desc1 =
11615     {
11616         .NumParameters = ARRAY_SIZE(constants_parameters1),
11617         .pParameters = constants_parameters1,
11618     };
11619 
11620 #if 0
11621     #define RS "DescriptorTable(CBV(b1, space = 7), " \
11622             "SRV(t16, numDescriptors = 8), " \
11623             "UAV(u3, numDescriptors = unbounded, offset = 44))"
11624 #endif
11625     static const DWORD descriptor_table_rootsig[] =
11626     {
11627         0x43425844, 0x0f92e563, 0x4766993f, 0x2304e283, 0x14f0d8dc, 0x00000001, 0x00000094, 0x00000001,
11628         0x00000024, 0x30535452, 0x00000068, 0x00000001, 0x00000001, 0x00000018, 0x00000000, 0x00000068,
11629         0x00000000, 0x00000000, 0x00000000, 0x00000024, 0x00000003, 0x0000002c, 0x00000002, 0x00000001,
11630         0x00000001, 0x00000007, 0xffffffff, 0x00000000, 0x00000008, 0x00000010, 0x00000000, 0xffffffff,
11631         0x00000001, 0xffffffff, 0x00000003, 0x00000000, 0x0000002c,
11632     };
11633     static const DWORD descriptor_table_rootsig1[] =
11634     {
11635         0x43425844, 0x739302ac, 0x9db37f96, 0x1ad9eec8, 0x7a5d08cb, 0x00000001, 0x000000a0, 0x00000001,
11636         0x00000024, 0x30535452, 0x00000074, 0x00000002, 0x00000001, 0x00000018, 0x00000000, 0x00000074,
11637         0x00000000, 0x00000000, 0x00000000, 0x00000024, 0x00000003, 0x0000002c, 0x00000002, 0x00000001,
11638         0x00000001, 0x00000007, 0x00000000, 0xffffffff, 0x00000000, 0x00000008, 0x00000010, 0x00000000,
11639         0x00000000, 0xffffffff, 0x00000001, 0xffffffff, 0x00000003, 0x00000000, 0x00000000, 0x0000002c,
11640     };
11641     static const D3D12_DESCRIPTOR_RANGE descriptor_ranges[] =
11642     {
11643         {D3D12_DESCRIPTOR_RANGE_TYPE_CBV,        1,  1, 7, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
11644         {D3D12_DESCRIPTOR_RANGE_TYPE_SRV,        8, 16, 0, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
11645         {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, UINT_MAX,  3, 0,                                   44},
11646     };
11647     static const D3D12_ROOT_PARAMETER descriptor_table_parameters[] =
11648     {
11649         {D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
11650                 .DescriptorTable = {ARRAY_SIZE(descriptor_ranges), descriptor_ranges}},
11651     };
11652     static const D3D12_ROOT_SIGNATURE_DESC descriptor_table_rootsig_desc =
11653     {
11654         .NumParameters = ARRAY_SIZE(descriptor_table_parameters),
11655         .pParameters = descriptor_table_parameters,
11656     };
11657     static const D3D12_DESCRIPTOR_RANGE1 descriptor_ranges1[] =
11658     {
11659         {D3D12_DESCRIPTOR_RANGE_TYPE_CBV,        1,  1, 7, 0, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
11660         {D3D12_DESCRIPTOR_RANGE_TYPE_SRV,        8, 16, 0, 0, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
11661         {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, UINT_MAX,  3, 0, 0,                                   44},
11662     };
11663     static const D3D12_ROOT_PARAMETER1 descriptor_table_parameters1[] =
11664     {
11665         {D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
11666                 .DescriptorTable = {ARRAY_SIZE(descriptor_ranges1), descriptor_ranges1}},
11667     };
11668     static const D3D12_ROOT_SIGNATURE_DESC1 descriptor_table_rootsig_desc1 =
11669     {
11670         .NumParameters = ARRAY_SIZE(descriptor_table_parameters1),
11671         .pParameters = descriptor_table_parameters1,
11672     };
11673 
11674 #if 0
11675     #define RS "DescriptorTable(CBV(b1, space = 7, flags = DESCRIPTORS_VOLATILE), " \
11676             "SRV(t16, numDescriptors = 8, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE), " \
11677             "UAV(u3, numDescriptors = unbounded, offset = 44, flags = DATA_STATIC))"
11678 #endif
11679     static const DWORD descriptor_table_flags_rootsig1[] =
11680     {
11681         0x43425844, 0xe77ffa8f, 0xfab552d5, 0x586e15d4, 0x4c186c26, 0x00000001, 0x000000a0, 0x00000001,
11682         0x00000024, 0x30535452, 0x00000074, 0x00000002, 0x00000001, 0x00000018, 0x00000000, 0x00000074,
11683         0x00000000, 0x00000000, 0x00000000, 0x00000024, 0x00000003, 0x0000002c, 0x00000002, 0x00000001,
11684         0x00000001, 0x00000007, 0x00000001, 0xffffffff, 0x00000000, 0x00000008, 0x00000010, 0x00000000,
11685         0x00000003, 0xffffffff, 0x00000001, 0xffffffff, 0x00000003, 0x00000000, 0x00000008, 0x0000002c,
11686     };
11687     static const D3D12_DESCRIPTOR_RANGE1 descriptor_ranges1_flags[] =
11688     {
11689         {D3D12_DESCRIPTOR_RANGE_TYPE_CBV,        1,  1, 7,
11690                 D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
11691         {D3D12_DESCRIPTOR_RANGE_TYPE_SRV,        8, 16, 0,
11692                 D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE | D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE,
11693                 D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
11694         {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, UINT_MAX,  3, 0,
11695                 D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC, 44},
11696     };
11697     static const D3D12_ROOT_PARAMETER1 descriptor_table_parameters1_flags[] =
11698     {
11699         {D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
11700                 .DescriptorTable = {ARRAY_SIZE(descriptor_ranges1_flags), descriptor_ranges1_flags}},
11701     };
11702     static const D3D12_ROOT_SIGNATURE_DESC1 descriptor_table_flags_rootsig_desc1 =
11703     {
11704         .NumParameters = ARRAY_SIZE(descriptor_table_parameters1_flags),
11705         .pParameters = descriptor_table_parameters1_flags,
11706     };
11707 
11708 #if 0
11709     #define RS "StaticSampler(s4)"
11710 #endif
11711     static const DWORD default_static_sampler_rootsig[] =
11712     {
11713         0x43425844, 0x2876b8ff, 0x935aaa0d, 0x5d2d344a, 0xe002147c, 0x00000001, 0x00000078, 0x00000001,
11714         0x00000024, 0x30535452, 0x0000004c, 0x00000001, 0x00000000, 0x00000018, 0x00000001, 0x00000018,
11715         0x00000000, 0x00000055, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000010, 0x00000004,
11716         0x00000002, 0x00000000, 0x7f7fffff, 0x00000004, 0x00000000, 0x00000000,
11717     };
11718     static const DWORD default_static_sampler_rootsig1[] =
11719     {
11720         0x43425844, 0x52b07945, 0x997c0a1e, 0xe4efb9e9, 0x0378e2d4, 0x00000001, 0x00000078, 0x00000001,
11721         0x00000024, 0x30535452, 0x0000004c, 0x00000002, 0x00000000, 0x00000018, 0x00000001, 0x00000018,
11722         0x00000000, 0x00000055, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000010, 0x00000004,
11723         0x00000002, 0x00000000, 0x7f7fffff, 0x00000004, 0x00000000, 0x00000000,
11724     };
11725     static const D3D12_STATIC_SAMPLER_DESC default_static_sampler_desc =
11726     {
11727         .Filter = D3D12_FILTER_ANISOTROPIC,
11728         .AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
11729         .AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
11730         .AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
11731         .MaxAnisotropy = 16,
11732         .ComparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL,
11733         .BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE,
11734         .MaxLOD = D3D12_FLOAT32_MAX,
11735         .ShaderRegister = 4,
11736     };
11737     static const D3D12_ROOT_SIGNATURE_DESC default_static_sampler_rootsig_desc =
11738     {
11739         .NumStaticSamplers = 1,
11740         .pStaticSamplers = &default_static_sampler_desc,
11741     };
11742     static const D3D12_ROOT_SIGNATURE_DESC1 default_static_sampler_rootsig_desc1 =
11743     {
11744         .NumStaticSamplers = 1,
11745         .pStaticSamplers = &default_static_sampler_desc,
11746     };
11747 
11748 #if 0
11749     #define RS "StaticSampler(s0, filter = FILTER_MIN_MAG_MIP_POINT, " \
11750             "addressV = TEXTURE_ADDRESS_CLAMP, visibility = SHADER_VISIBILITY_PIXEL), " \
11751             "StaticSampler(s0, filter = FILTER_MIN_MAG_POINT_MIP_LINEAR, " \
11752             "AddressW = TEXTURE_ADDRESS_BORDER, MipLODBias = 1, maxLod = 10, " \
11753             "borderColor = STATIC_BORDER_COLOR_OPAQUE_BLACK, space = 3)"
11754 #endif
11755     static const DWORD static_samplers_rootsig[] =
11756     {
11757         0x43425844, 0x52ed526c, 0x892c2d7c, 0xb8ab1123, 0x7e3a727d, 0x00000001, 0x000000ac, 0x00000001,
11758         0x00000024, 0x30535452, 0x00000080, 0x00000001, 0x00000000, 0x00000018, 0x00000002, 0x00000018,
11759         0x00000000, 0x00000000, 0x00000001, 0x00000003, 0x00000001, 0x00000000, 0x00000010, 0x00000004,
11760         0x00000002, 0x00000000, 0x7f7fffff, 0x00000000, 0x00000000, 0x00000005, 0x00000001, 0x00000001,
11761         0x00000001, 0x00000004, 0x3f800000, 0x00000010, 0x00000004, 0x00000001, 0x00000000, 0x41200000,
11762         0x00000000, 0x00000003, 0x00000000,
11763     };
11764     static const DWORD static_samplers_rootsig1[] =
11765     {
11766         0x43425844, 0xcf44eb9e, 0xdbeaed6b, 0xb8d52b6f, 0x0be01c3b, 0x00000001, 0x000000ac, 0x00000001,
11767         0x00000024, 0x30535452, 0x00000080, 0x00000002, 0x00000000, 0x00000018, 0x00000002, 0x00000018,
11768         0x00000000, 0x00000000, 0x00000001, 0x00000003, 0x00000001, 0x00000000, 0x00000010, 0x00000004,
11769         0x00000002, 0x00000000, 0x7f7fffff, 0x00000000, 0x00000000, 0x00000005, 0x00000001, 0x00000001,
11770         0x00000001, 0x00000004, 0x3f800000, 0x00000010, 0x00000004, 0x00000001, 0x00000000, 0x41200000,
11771         0x00000000, 0x00000003, 0x00000000,
11772     };
11773     static const D3D12_STATIC_SAMPLER_DESC static_sampler_descs[] =
11774     {
11775         {
11776             .Filter = D3D12_FILTER_MIN_MAG_MIP_POINT,
11777             .AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
11778             .AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
11779             .AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
11780             .MaxAnisotropy = 16,
11781             .ComparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL,
11782             .BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE,
11783             .MaxLOD = D3D12_FLOAT32_MAX,
11784             .ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
11785         },
11786         {
11787             .Filter = D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR,
11788             .AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
11789             .AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
11790             .AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER,
11791             .MipLODBias = 1.0f,
11792             .MaxAnisotropy = 16,
11793             .ComparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL,
11794             .BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK,
11795             .MaxLOD = 10.0f,
11796             .RegisterSpace = 3,
11797         }
11798     };
11799     static const D3D12_ROOT_SIGNATURE_DESC static_samplers_rootsig_desc =
11800     {
11801         .NumStaticSamplers = ARRAY_SIZE(static_sampler_descs),
11802         .pStaticSamplers = static_sampler_descs,
11803     };
11804     static const D3D12_ROOT_SIGNATURE_DESC1 static_samplers_rootsig_desc1 =
11805     {
11806         .NumStaticSamplers = ARRAY_SIZE(static_sampler_descs),
11807         .pStaticSamplers = static_sampler_descs,
11808     };
11809 
11810     static const struct test
11811     {
11812         D3D12_SHADER_BYTECODE code;
11813         D3D12_SHADER_BYTECODE code1;
11814         const D3D12_ROOT_SIGNATURE_DESC *desc;
11815         const D3D12_ROOT_SIGNATURE_DESC1 *desc1;
11816     }
11817     tests[] =
11818     {
11819         {
11820             {empty_rootsig, sizeof(empty_rootsig)},
11821             {empty_rootsig1, sizeof(empty_rootsig1)},
11822             &empty_rootsig_desc, &empty_rootsig_desc1,
11823         },
11824         {
11825             {ia_rootsig, sizeof(ia_rootsig)},
11826             {ia_rootsig1, sizeof(ia_rootsig1)},
11827             &ia_rootsig_desc, &ia_rootsig_desc1,
11828         },
11829         {
11830             {deny_ps_rootsig, sizeof(deny_ps_rootsig)},
11831             {deny_ps_rootsig1, sizeof(deny_ps_rootsig1)},
11832             &deny_ps_rootsig_desc, &deny_ps_rootsig_desc1,
11833         },
11834         {
11835             {cbv_rootsig, sizeof(cbv_rootsig)},
11836             {cbv_rootsig1, sizeof(cbv_rootsig1)},
11837             &cbv_rootsig_desc, &cbv_rootsig_desc1,
11838         },
11839         {
11840             {cbv2_rootsig, sizeof(cbv2_rootsig)},
11841             {cbv2_rootsig1, sizeof(cbv2_rootsig1)},
11842             &cbv2_rootsig_desc, &cbv2_rootsig_desc1,
11843         },
11844         {
11845             {srv_rootsig, sizeof(srv_rootsig)},
11846             {srv_rootsig1, sizeof(srv_rootsig1)},
11847             &srv_rootsig_desc, &srv_rootsig_desc1,
11848         },
11849         {
11850             {uav_rootsig, sizeof(uav_rootsig)},
11851             {uav_rootsig1, sizeof(uav_rootsig1)},
11852             &uav_rootsig_desc, &uav_rootsig_desc1,
11853         },
11854         {
11855             {NULL},
11856             {root_descriptors_rootsig1, sizeof(root_descriptors_rootsig1)},
11857             &root_descriptors_desc, &root_descriptors_desc1,
11858         },
11859         {
11860             {constants_rootsig, sizeof(constants_rootsig)},
11861             {constants_rootsig1, sizeof(constants_rootsig1)},
11862             &constants_rootsig_desc, &constants_rootsig_desc1,
11863         },
11864         {
11865             {descriptor_table_rootsig, sizeof(descriptor_table_rootsig)},
11866             {descriptor_table_rootsig1, sizeof(descriptor_table_rootsig1)},
11867             &descriptor_table_rootsig_desc, &descriptor_table_rootsig_desc1,
11868         },
11869         {
11870             {NULL},
11871             {descriptor_table_flags_rootsig1, sizeof(descriptor_table_flags_rootsig1)},
11872             &descriptor_table_rootsig_desc, &descriptor_table_flags_rootsig_desc1,
11873         },
11874         {
11875             {default_static_sampler_rootsig, sizeof(default_static_sampler_rootsig)},
11876             {default_static_sampler_rootsig1, sizeof(default_static_sampler_rootsig1)},
11877             &default_static_sampler_rootsig_desc, &default_static_sampler_rootsig_desc1,
11878         },
11879         {
11880             {static_samplers_rootsig, sizeof(static_samplers_rootsig)},
11881             {static_samplers_rootsig1, sizeof(static_samplers_rootsig1)},
11882             &static_samplers_rootsig_desc, &static_samplers_rootsig_desc1,
11883         },
11884     };
11885 
11886     hr = D3D12CreateRootSignatureDeserializer(empty_rootsig, sizeof(empty_rootsig),
11887             &IID_IUnknown, (void **)&deserializer);
11888     ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
11889     hr = D3D12CreateRootSignatureDeserializer(empty_rootsig, sizeof(empty_rootsig),
11890             &IID_ID3D12VersionedRootSignatureDeserializer, (void **)&deserializer);
11891     ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
11892 
11893     hr = D3D12CreateRootSignatureDeserializer(empty_rootsig, sizeof(empty_rootsig),
11894             &IID_ID3D12RootSignatureDeserializer, (void **)&deserializer);
11895     ok(hr == S_OK, "Failed to create deserializer, hr %#x.\n", hr);
11896 
11897     check_interface(deserializer, &IID_IUnknown, false);
11898     check_interface(deserializer, &IID_ID3D12RootSignatureDeserializer, true);
11899     check_interface(deserializer, &IID_ID3D12VersionedRootSignatureDeserializer, false);
11900     check_interface(deserializer, &IID_ID3D12Object, false);
11901     check_interface(deserializer, &IID_ID3D12DeviceChild, false);
11902     check_interface(deserializer, &IID_ID3D12Pageable, false);
11903 
11904     refcount = ID3D12RootSignatureDeserializer_Release(deserializer);
11905     ok(!refcount, "ID3D12RootSignatureDeserializer has %u references left.\n", (unsigned int)refcount);
11906 
11907     for (i = 0; i < ARRAY_SIZE(tests); ++i)
11908     {
11909         const struct test *t = &tests[i];
11910 
11911         vkd3d_test_set_context("Test %u", i);
11912 
11913         check_root_signature_deserialization(&t->code, t->desc, t->desc1);
11914         check_root_signature_serialization(&t->code, t->desc);
11915 
11916         blob = (ID3DBlob *)0xdeadbeef;
11917         hr = D3D12SerializeRootSignature(t->desc, D3D_ROOT_SIGNATURE_VERSION_1_1, &blob, NULL);
11918         ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
11919         ok(blob == (ID3DBlob *)0xdeadbeef, "Got unexpected blob %p.\n", blob);
11920 
11921         if (!pfn_D3D12CreateVersionedRootSignatureDeserializer)
11922             continue;
11923 
11924         check_root_signature_deserialization1(&t->code1, t->desc, t->desc1);
11925         check_root_signature_serialization1(&t->code1, t->desc1);
11926     }
11927     vkd3d_test_set_context(NULL);
11928 
11929     if (!pfn_D3D12CreateVersionedRootSignatureDeserializer)
11930     {
11931         skip("D3D12CreateVersionedRootSignatureDeserializer is not available.\n");
11932         return;
11933     }
11934 
11935     hr = pfn_D3D12CreateVersionedRootSignatureDeserializer(empty_rootsig, sizeof(empty_rootsig),
11936             &IID_IUnknown, (void **)&versioned_deserializer);
11937     ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
11938     hr = pfn_D3D12CreateVersionedRootSignatureDeserializer(empty_rootsig, sizeof(empty_rootsig),
11939             &IID_ID3D12RootSignatureDeserializer, (void **)&versioned_deserializer);
11940     ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
11941 
11942     hr = pfn_D3D12CreateVersionedRootSignatureDeserializer(empty_rootsig, sizeof(empty_rootsig),
11943             &IID_ID3D12VersionedRootSignatureDeserializer, (void **)&versioned_deserializer);
11944     ok(hr == S_OK, "Failed to create deserializer, hr %#x.\n", hr);
11945 
11946     check_interface(versioned_deserializer, &IID_IUnknown, false);
11947     check_interface(versioned_deserializer, &IID_ID3D12RootSignatureDeserializer, false);
11948     check_interface(versioned_deserializer, &IID_ID3D12VersionedRootSignatureDeserializer, true);
11949     check_interface(versioned_deserializer, &IID_ID3D12Object, false);
11950     check_interface(versioned_deserializer, &IID_ID3D12DeviceChild, false);
11951     check_interface(versioned_deserializer, &IID_ID3D12Pageable, false);
11952 
11953     refcount = ID3D12VersionedRootSignatureDeserializer_Release(versioned_deserializer);
11954     ok(!refcount, "ID3D12VersionedRootSignatureDeserializer has %u references left.\n", (unsigned int)refcount);
11955 }
11956 
test_cs_constant_buffer(void)11957 static void test_cs_constant_buffer(void)
11958 {
11959     D3D12_CPU_DESCRIPTOR_HANDLE cpu_descriptor_handle;
11960     D3D12_GPU_DESCRIPTOR_HANDLE gpu_descriptor_handle;
11961     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
11962     D3D12_DESCRIPTOR_RANGE descriptor_ranges[1];
11963     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
11964     ID3D12GraphicsCommandList *command_list;
11965     D3D12_ROOT_PARAMETER root_parameters[2];
11966     ID3D12DescriptorHeap *descriptor_heap;
11967     D3D12_DESCRIPTOR_HEAP_DESC heap_desc;
11968     ID3D12RootSignature *root_signature;
11969     ID3D12PipelineState *pipeline_state;
11970     ID3D12Resource *resource, *cb;
11971     unsigned int descriptor_size;
11972     struct resource_readback rb;
11973     struct test_context context;
11974     ID3D12CommandQueue *queue;
11975     ID3D12Device *device;
11976     unsigned int i;
11977     float value;
11978     HRESULT hr;
11979 
11980     static const DWORD cs_code[] =
11981     {
11982 #if 0
11983         cbuffer cb : register(b7)
11984         {
11985             float value;
11986         };
11987 
11988         RWBuffer<float> buffer;
11989 
11990         [numthreads(32, 1, 1)]
11991         void main(uint3 group_id : SV_groupID, uint group_index : SV_GroupIndex)
11992         {
11993             uint global_index = 32 * group_id.x + group_index;
11994             buffer[global_index] = value;
11995         }
11996 #endif
11997         0x43425844, 0xbcbca6fb, 0x0bd883e5, 0x8e0848ea, 0xaf152cfd, 0x00000001, 0x000000e8, 0x00000003,
11998         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
11999         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000094, 0x00050050, 0x00000025, 0x0100086a,
12000         0x04000059, 0x00208e46, 0x00000007, 0x00000001, 0x0400089c, 0x0011e000, 0x00000000, 0x00005555,
12001         0x0200005f, 0x00024000, 0x0200005f, 0x00021012, 0x02000068, 0x00000001, 0x0400009b, 0x00000020,
12002         0x00000001, 0x00000001, 0x07000023, 0x00100012, 0x00000000, 0x0002100a, 0x00004001, 0x00000020,
12003         0x0002400a, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100006, 0x00000000, 0x00208006, 0x00000007,
12004         0x00000000, 0x0100003e,
12005     };
12006 
12007     if (!init_compute_test_context(&context))
12008         return;
12009     device = context.device;
12010     command_list = context.list;
12011     queue = context.queue;
12012 
12013     value = 2.0f;
12014     cb = create_upload_buffer(context.device, sizeof(value), &value);
12015 
12016     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
12017     descriptor_ranges[0].NumDescriptors = 4;
12018     descriptor_ranges[0].BaseShaderRegister = 0;
12019     descriptor_ranges[0].RegisterSpace = 0;
12020     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
12021     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
12022     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
12023     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
12024     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
12025     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
12026     root_parameters[1].Descriptor.ShaderRegister = 7;
12027     root_parameters[1].Descriptor.RegisterSpace = 0;
12028     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
12029     root_signature_desc.NumParameters = 2;
12030     root_signature_desc.pParameters = root_parameters;
12031     root_signature_desc.NumStaticSamplers = 0;
12032     root_signature_desc.pStaticSamplers = NULL;
12033     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
12034     hr = create_root_signature(device, &root_signature_desc, &root_signature);
12035     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
12036 
12037     pipeline_state = create_compute_pipeline_state(device, root_signature,
12038             shader_bytecode(cs_code, sizeof(cs_code)));
12039 
12040     heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
12041     heap_desc.NumDescriptors = 4;
12042     heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
12043     heap_desc.NodeMask = 0;
12044     hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc,
12045             &IID_ID3D12DescriptorHeap, (void **)&descriptor_heap);
12046     ok(SUCCEEDED(hr), "Failed to create descriptor heap, hr %#x.\n", hr);
12047 
12048     descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(device,
12049             D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
12050 
12051     cpu_descriptor_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(descriptor_heap);
12052     gpu_descriptor_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap);
12053 
12054     resource = create_default_buffer(device, 64 * sizeof(float),
12055             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
12056 
12057     uav_desc.Format = DXGI_FORMAT_R32_FLOAT;
12058     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
12059     uav_desc.Buffer.FirstElement = 0;
12060     uav_desc.Buffer.NumElements = 64;
12061     uav_desc.Buffer.StructureByteStride = 0;
12062     uav_desc.Buffer.CounterOffsetInBytes = 0;
12063     uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
12064     ID3D12Device_CreateUnorderedAccessView(device, resource, NULL, &uav_desc, cpu_descriptor_handle);
12065     /* For tier 1 hardware all descriptors must be populated. */
12066     for (i = 1; i < heap_desc.NumDescriptors; ++i)
12067     {
12068         cpu_descriptor_handle.ptr += descriptor_size;
12069         ID3D12Device_CreateUnorderedAccessView(device, NULL, NULL, &uav_desc, cpu_descriptor_handle);
12070     }
12071 
12072     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, root_signature);
12073     ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(command_list, 1,
12074             ID3D12Resource_GetGPUVirtualAddress(cb));
12075     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
12076     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_descriptor_handle);
12077     ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
12078     ID3D12GraphicsCommandList_Dispatch(command_list, 2, 1, 1);
12079 
12080     transition_sub_resource_state(command_list, resource, 0,
12081             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
12082     get_buffer_readback_with_command_list(resource, uav_desc.Format, &rb, queue, command_list);
12083     check_readback_data_float(&rb, NULL, 2.0f, 0);
12084     release_resource_readback(&rb);
12085 
12086     value = 6.0f;
12087     update_buffer_data(cb, 0, sizeof(value), &value);
12088 
12089     reset_command_list(command_list, context.allocator);
12090     transition_sub_resource_state(command_list, resource, 0,
12091             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
12092 
12093     ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
12094     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, root_signature);
12095     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
12096     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_descriptor_handle);
12097     ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(command_list, 1,
12098             ID3D12Resource_GetGPUVirtualAddress(cb));
12099     ID3D12GraphicsCommandList_Dispatch(command_list, 2, 1, 1);
12100 
12101     transition_sub_resource_state(command_list, resource, 0,
12102             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
12103     get_buffer_readback_with_command_list(resource, uav_desc.Format, &rb, queue, command_list);
12104     check_readback_data_float(&rb, NULL, 6.0f, 0);
12105     release_resource_readback(&rb);
12106 
12107     ID3D12Resource_Release(cb);
12108     ID3D12Resource_Release(resource);
12109     ID3D12RootSignature_Release(root_signature);
12110     ID3D12PipelineState_Release(pipeline_state);
12111     ID3D12DescriptorHeap_Release(descriptor_heap);
12112     destroy_test_context(&context);
12113 }
12114 
test_constant_buffer_relative_addressing(void)12115 static void test_constant_buffer_relative_addressing(void)
12116 {
12117     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
12118     D3D12_ROOT_PARAMETER root_parameters[2];
12119     ID3D12GraphicsCommandList *command_list;
12120     struct resource_readback rb;
12121     struct test_context context;
12122     ID3D12CommandQueue *queue;
12123     ID3D12Resource *uav, *cb;
12124     ID3D12Device *device;
12125     unsigned int i;
12126     HRESULT hr;
12127 
12128     static const DWORD cs_code[] =
12129     {
12130 #if 0
12131         cbuffer b0
12132         {
12133             uint4 pad;
12134             uint4 data[4];
12135         };
12136 
12137         RWByteAddressBuffer u0;
12138 
12139         [numthreads(4, 1, 1)]
12140         void main(uint tid : SV_GroupThreadID)
12141         {
12142             uint location = 4 * tid;
12143             u0.Store4(4 * location, data[tid]);
12144         }
12145 #endif
12146         0x43425844, 0x759a28a0, 0xdd34cd41, 0x73702692, 0x739a66ea, 0x00000001, 0x000000f0, 0x00000003,
12147         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
12148         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x0000009c, 0x00050050, 0x00000027, 0x0100086a,
12149         0x04000859, 0x00208e46, 0x00000000, 0x00000005, 0x0300009d, 0x0011e000, 0x00000000, 0x0200005f,
12150         0x00022012, 0x02000068, 0x00000001, 0x0400009b, 0x00000004, 0x00000001, 0x00000001, 0x06000029,
12151         0x00100012, 0x00000000, 0x0002200a, 0x00004001, 0x00000004, 0x04000036, 0x00100022, 0x00000000,
12152         0x0002200a, 0x0a0000a6, 0x0011e0f2, 0x00000000, 0x0010000a, 0x00000000, 0x06208e46, 0x00000000,
12153         0x00000001, 0x0010001a, 0x00000000, 0x0100003e,
12154     };
12155     static const struct uvec4 cb_data[] =
12156     {
12157         {0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef},
12158         {1, 2, 3, 4},
12159         {4, 4, 9, 8},
12160         {4, 5, 6, 7},
12161         {6, 0, 6, 0},
12162     };
12163 
12164     if (!init_compute_test_context(&context))
12165         return;
12166     device = context.device;
12167     command_list = context.list;
12168     queue = context.queue;
12169 
12170     cb = create_upload_buffer(context.device, sizeof(cb_data), &cb_data);
12171 
12172     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
12173     root_parameters[0].Descriptor.ShaderRegister = 0;
12174     root_parameters[0].Descriptor.RegisterSpace = 0;
12175     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
12176     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
12177     root_parameters[1].Descriptor.ShaderRegister = 0;
12178     root_parameters[1].Descriptor.RegisterSpace = 0;
12179     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
12180     root_signature_desc.NumParameters = 2;
12181     root_signature_desc.pParameters = root_parameters;
12182     root_signature_desc.NumStaticSamplers = 0;
12183     root_signature_desc.pStaticSamplers = NULL;
12184     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
12185     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
12186     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
12187 
12188     context.pipeline_state = create_compute_pipeline_state(device, context.root_signature,
12189             shader_bytecode(cs_code, sizeof(cs_code)));
12190 
12191     uav = create_default_buffer(device, 16 * sizeof(uint32_t),
12192             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
12193 
12194     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
12195     ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list, 0,
12196             ID3D12Resource_GetGPUVirtualAddress(uav));
12197     ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(command_list, 1,
12198             ID3D12Resource_GetGPUVirtualAddress(cb));
12199     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
12200     ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
12201 
12202     transition_sub_resource_state(command_list, uav, 0,
12203             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
12204     get_buffer_readback_with_command_list(uav, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
12205     for (i = 0; i < rb.width; ++i)
12206     {
12207         unsigned int got = get_readback_uint(&rb, i, 0, 0);
12208         const unsigned int *expected = &cb_data[1].x;
12209         ok(got == expected[i], "Got %#x, expected %#x at %u.\n", got, expected[i], i);
12210     }
12211     release_resource_readback(&rb);
12212 
12213     ID3D12Resource_Release(cb);
12214     ID3D12Resource_Release(uav);
12215     destroy_test_context(&context);
12216 }
12217 
test_immediate_constant_buffer(void)12218 static void test_immediate_constant_buffer(void)
12219 {
12220     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
12221     ID3D12GraphicsCommandList *command_list;
12222     struct test_context_desc desc;
12223     struct test_context context;
12224     unsigned int index[4] = {0};
12225     ID3D12CommandQueue *queue;
12226     ID3D12Resource *cb;
12227     unsigned int i;
12228 
12229     static const DWORD ps_code[] =
12230     {
12231 #if 0
12232         uint index;
12233 
12234         static const int int_array[6] =
12235         {
12236             310, 111, 212, -513, -318, 0,
12237         };
12238 
12239         static const uint uint_array[6] =
12240         {
12241             2, 7, 0x7f800000, 0xff800000, 0x7fc00000, 0
12242         };
12243 
12244         static const float float_array[6] =
12245         {
12246             76, 83.5f, 0.5f, 0.75f, -0.5f, 0.0f,
12247         };
12248 
12249         float4 main() : SV_Target
12250         {
12251             return float4(int_array[index], uint_array[index], float_array[index], 1.0f);
12252         }
12253 #endif
12254         0x43425844, 0xbad068da, 0xd631ea3c, 0x41648374, 0x3ccd0120, 0x00000001, 0x00000184, 0x00000003,
12255         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
12256         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
12257         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x0000010c, 0x00000040, 0x00000043,
12258         0x00001835, 0x0000001a, 0x00000136, 0x00000002, 0x42980000, 0x00000000, 0x0000006f, 0x00000007,
12259         0x42a70000, 0x00000000, 0x000000d4, 0x7f800000, 0x3f000000, 0x00000000, 0xfffffdff, 0xff800000,
12260         0x3f400000, 0x00000000, 0xfffffec2, 0x7fc00000, 0xbf000000, 0x00000000, 0x00000000, 0x00000000,
12261         0x00000000, 0x00000000, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2,
12262         0x00000000, 0x02000068, 0x00000001, 0x05000036, 0x00102082, 0x00000000, 0x00004001, 0x3f800000,
12263         0x06000036, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x06000056, 0x00102022,
12264         0x00000000, 0x0090901a, 0x0010000a, 0x00000000, 0x0600002b, 0x00102012, 0x00000000, 0x0090900a,
12265         0x0010000a, 0x00000000, 0x06000036, 0x00102042, 0x00000000, 0x0090902a, 0x0010000a, 0x00000000,
12266         0x0100003e,
12267     };
12268     static const unsigned int MAX_CB_SIZE = D3D12_REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT * sizeof(struct vec4);
12269     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
12270     static struct vec4 expected_result[] =
12271     {
12272         { 310.0f,          2.0f, 76.00f, 1.0f},
12273         { 111.0f,          7.0f, 83.50f, 1.0f},
12274         { 212.0f, 2139095040.0f,  0.50f, 1.0f},
12275         {-513.0f, 4286578688.0f,  0.75f, 1.0f},
12276         {-318.0f, 2143289344.0f, -0.50f, 1.0f},
12277         {   0.0f,          0.0f,  0.0f,  1.0f},
12278     };
12279 
12280     memset(&desc, 0, sizeof(desc));
12281     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
12282     desc.no_root_signature = true;
12283     if (!init_test_context(&context, &desc))
12284         return;
12285     command_list = context.list;
12286     queue = context.queue;
12287 
12288     context.root_signature = create_cb_root_signature(context.device,
12289             0, D3D12_SHADER_VISIBILITY_PIXEL, D3D12_ROOT_SIGNATURE_FLAG_NONE);
12290     context.pipeline_state = create_pipeline_state(context.device,
12291             context.root_signature, desc.rt_format, NULL, &ps, NULL);
12292 
12293     cb = create_upload_buffer(context.device, 2 * MAX_CB_SIZE, NULL);
12294 
12295     for (i = 0; i < ARRAY_SIZE(expected_result); ++i)
12296     {
12297         *index = i;
12298         update_buffer_data(cb, 0, sizeof(index), index);
12299 
12300         if (i)
12301             transition_resource_state(command_list, context.render_target,
12302                     D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
12303 
12304         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
12305 
12306         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
12307         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
12308         ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
12309                 ID3D12Resource_GetGPUVirtualAddress(cb));
12310         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
12311         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
12312         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
12313         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
12314         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
12315 
12316         transition_resource_state(command_list, context.render_target,
12317                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
12318         check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_result[i], 0);
12319 
12320         reset_command_list(command_list, context.allocator);
12321     }
12322 
12323     ID3D12Resource_Release(cb);
12324     destroy_test_context(&context);
12325 }
12326 
test_root_constants(void)12327 static void test_root_constants(void)
12328 {
12329     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
12330     static const unsigned int constants[4] = {0, 1, 0, 2};
12331 
12332     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
12333     D3D12_ROOT_PARAMETER root_parameters[3];
12334     ID3D12GraphicsCommandList *command_list;
12335     struct vec4 vs_cb_color, ps_cb_color;
12336     struct test_context_desc desc;
12337     struct test_context context;
12338     struct vec4 expected_result;
12339     ID3D12CommandQueue *queue;
12340     HRESULT hr;
12341 
12342     static const DWORD ps_uint_constant_code[] =
12343     {
12344 #if 0
12345         uint4 constants;
12346 
12347         float4 main() : SV_Target
12348         {
12349             return (float4)constants;
12350         }
12351 #endif
12352         0x43425844, 0xf744186d, 0x6805439a, 0x491c3625, 0xe3e4053c, 0x00000001, 0x000000bc, 0x00000003,
12353         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
12354         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
12355         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000044, 0x00000050, 0x00000011,
12356         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
12357         0x06000056, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e,
12358     };
12359     static const D3D12_SHADER_BYTECODE ps_uint_constant = {ps_uint_constant_code, sizeof(ps_uint_constant_code)};
12360     static const DWORD vs_color_code[] =
12361     {
12362 #if 0
12363         float4 constant_color;
12364 
12365         void main(uint id : SV_VertexID,
12366                 out float4 position : SV_Position, out float4 color : COLOR)
12367         {
12368             float2 coords = float2((id << 1) & 2, id & 2);
12369             position = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1);
12370             color = constant_color;
12371         }
12372 #endif
12373         0x43425844, 0x7c3173fb, 0xdd990625, 0x290ad676, 0x50b41793, 0x00000001, 0x000001e0, 0x00000003,
12374         0x0000002c, 0x00000060, 0x000000b4, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
12375         0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000101, 0x565f5653, 0x65747265, 0x00444978,
12376         0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003,
12377         0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
12378         0x505f5653, 0x7469736f, 0x006e6f69, 0x4f4c4f43, 0xabab0052, 0x58454853, 0x00000124, 0x00010050,
12379         0x00000049, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000060, 0x00101012,
12380         0x00000000, 0x00000006, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2,
12381         0x00000001, 0x02000068, 0x00000001, 0x0b00008c, 0x00100012, 0x00000000, 0x00004001, 0x00000001,
12382         0x00004001, 0x00000001, 0x0010100a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100042,
12383         0x00000000, 0x0010100a, 0x00000000, 0x00004001, 0x00000002, 0x05000056, 0x00100032, 0x00000000,
12384         0x00100086, 0x00000000, 0x0f000032, 0x00102032, 0x00000000, 0x00100046, 0x00000000, 0x00004002,
12385         0x40000000, 0xc0000000, 0x00000000, 0x00000000, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000,
12386         0x00000000, 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
12387         0x3f800000, 0x06000036, 0x001020f2, 0x00000001, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e,
12388     };
12389     static const D3D12_SHADER_BYTECODE vs_color = {vs_color_code, sizeof(vs_color_code)};
12390     static const DWORD ps_color_code[] =
12391     {
12392 #if 0
12393         float4 color;
12394 
12395         float4 main(float4 position : SV_POSITION, float4 in_color : COLOR) : SV_Target
12396         {
12397             if (any(color != in_color))
12398                 return float4(0.0f, 0.0f, 1.0f, 1.0f);
12399             return in_color;
12400         }
12401 #endif
12402         0x43425844, 0xb1e305a3, 0x962c4d64, 0x6b2c5515, 0x4fb4f524, 0x00000001, 0x0000019c, 0x00000003,
12403         0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
12404         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000,
12405         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
12406         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
12407         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000e0, 0x00000050,
12408         0x00000038, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03001062, 0x001010f2,
12409         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x08000039, 0x001000f2,
12410         0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00101e46, 0x00000001, 0x0700003c, 0x00100032,
12411         0x00000000, 0x00100ae6, 0x00000000, 0x00100046, 0x00000000, 0x0700003c, 0x00100012, 0x00000000,
12412         0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a, 0x00000000, 0x08000036,
12413         0x001020f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x0100003e,
12414         0x01000015, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e,
12415     };
12416     static const D3D12_SHADER_BYTECODE ps_color = {ps_color_code, sizeof(ps_color_code)};
12417     static const DWORD vs_mix_code[] =
12418     {
12419 #if 0
12420         cbuffer shared_cb
12421         {
12422             uint token;
12423             uint op;
12424         };
12425 
12426         cbuffer vs_cb
12427         {
12428             float4 padding;
12429             float4 vs_color;
12430         };
12431 
12432         void main(uint id : SV_VertexID,
12433                 out float4 position : SV_Position, out float4 color : COLOR,
12434                 out uint vs_token : TOKEN)
12435         {
12436             float2 coords = float2((id << 1) & 2, id & 2);
12437             position = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1);
12438             color = vs_color;
12439             vs_token = token;
12440         }
12441 #endif
12442         0x43425844, 0xb5bc00c3, 0x6b5041fe, 0xd55d1d86, 0x34a2a229, 0x00000001, 0x00000230, 0x00000003,
12443         0x0000002c, 0x00000060, 0x000000d0, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
12444         0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000101, 0x565f5653, 0x65747265, 0x00444978,
12445         0x4e47534f, 0x00000068, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, 0x00000003,
12446         0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
12447         0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000e01, 0x505f5653, 0x7469736f,
12448         0x006e6f69, 0x4f4c4f43, 0x4f540052, 0x004e454b, 0x58454853, 0x00000158, 0x00010050, 0x00000056,
12449         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001,
12450         0x00000002, 0x04000060, 0x00101012, 0x00000000, 0x00000006, 0x04000067, 0x001020f2, 0x00000000,
12451         0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x03000065, 0x00102012, 0x00000002, 0x02000068,
12452         0x00000001, 0x0b00008c, 0x00100012, 0x00000000, 0x00004001, 0x00000001, 0x00004001, 0x00000001,
12453         0x0010100a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100042, 0x00000000, 0x0010100a,
12454         0x00000000, 0x00004001, 0x00000002, 0x05000056, 0x00100032, 0x00000000, 0x00100086, 0x00000000,
12455         0x0f000032, 0x00102032, 0x00000000, 0x00100046, 0x00000000, 0x00004002, 0x40000000, 0xc0000000,
12456         0x00000000, 0x00000000, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000, 0x08000036,
12457         0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x06000036,
12458         0x001020f2, 0x00000001, 0x00208e46, 0x00000001, 0x00000001, 0x06000036, 0x00102012, 0x00000002,
12459         0x0020800a, 0x00000000, 0x00000000, 0x0100003e,
12460     };
12461     static const D3D12_SHADER_BYTECODE vs_mix = {vs_mix_code, sizeof(vs_mix_code)};
12462     static const DWORD ps_mix_code[] =
12463     {
12464 #if 0
12465         cbuffer shared_cb
12466         {
12467             uint token;
12468             uint op;
12469         };
12470 
12471         cbuffer ps_cb
12472         {
12473             float4 ps_color;
12474         };
12475 
12476         float4 main(float4 position : SV_POSITION, float4 vs_color : COLOR,
12477                 uint vs_token : TOKEN) : SV_Target
12478         {
12479             if (token != vs_token)
12480                 return (float4)1.0f;
12481 
12482             switch (op)
12483             {
12484                 case 0: return vs_color;
12485                 case 1: return ps_color;
12486                 case 2: return vs_color * ps_color;
12487                 default: return (float4)0.0f;
12488             }
12489         }
12490 #endif
12491         0x43425844, 0x128ef4ce, 0xa1c46517, 0x34ca76f3, 0x3c7d6112, 0x00000001, 0x00000240, 0x00000003,
12492         0x0000002c, 0x0000009c, 0x000000d0, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
12493         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000,
12494         0x00000003, 0x00000001, 0x00000f0f, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000002,
12495         0x00000101, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0x4f540052, 0x004e454b, 0x4e47534f,
12496         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
12497         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000168, 0x00000050, 0x0000005a,
12498         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001,
12499         0x00000001, 0x03001062, 0x001010f2, 0x00000001, 0x03000862, 0x00101012, 0x00000002, 0x03000065,
12500         0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x08000027, 0x00100012, 0x00000000, 0x0020800a,
12501         0x00000000, 0x00000000, 0x0010100a, 0x00000002, 0x0304001f, 0x0010000a, 0x00000000, 0x08000036,
12502         0x001020f2, 0x00000000, 0x00004002, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x0100003e,
12503         0x01000015, 0x0400004c, 0x0020801a, 0x00000000, 0x00000000, 0x03000006, 0x00004001, 0x00000000,
12504         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e, 0x03000006, 0x00004001,
12505         0x00000001, 0x06000036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000001, 0x00000000, 0x0100003e,
12506         0x03000006, 0x00004001, 0x00000002, 0x08000038, 0x001020f2, 0x00000000, 0x00101e46, 0x00000001,
12507         0x00208e46, 0x00000001, 0x00000000, 0x0100003e, 0x0100000a, 0x08000036, 0x001020f2, 0x00000000,
12508         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e, 0x01000017, 0x0100003e,
12509     };
12510     static const D3D12_SHADER_BYTECODE ps_mix = {ps_mix_code, sizeof(ps_mix_code)};
12511 
12512     memset(&desc, 0, sizeof(desc));
12513     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
12514     desc.no_root_signature = true;
12515     if (!init_test_context(&context, &desc))
12516         return;
12517     command_list = context.list;
12518     queue = context.queue;
12519 
12520     context.root_signature = create_32bit_constants_root_signature(context.device,
12521             0, ARRAY_SIZE(constants), D3D12_SHADER_VISIBILITY_ALL);
12522     context.pipeline_state = create_pipeline_state(context.device,
12523             context.root_signature, desc.rt_format, NULL, &ps_uint_constant, NULL);
12524 
12525     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
12526     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
12527     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
12528     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0,
12529             ARRAY_SIZE(constants), constants, 0);
12530     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
12531     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
12532     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
12533     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
12534     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
12535 
12536     transition_resource_state(command_list, context.render_target,
12537             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
12538     expected_result.x = constants[0];
12539     expected_result.y = constants[1];
12540     expected_result.z = constants[2];
12541     expected_result.w = constants[3];
12542     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_result, 0);
12543 
12544     reset_command_list(command_list, context.allocator);
12545 
12546     ID3D12PipelineState_Release(context.pipeline_state);
12547     ID3D12RootSignature_Release(context.root_signature);
12548 
12549     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
12550     root_parameters[0].Constants.ShaderRegister = 0;
12551     root_parameters[0].Constants.RegisterSpace = 0;
12552     root_parameters[0].Constants.Num32BitValues = 4;
12553     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
12554     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
12555     root_parameters[1].Constants.ShaderRegister = 0;
12556     root_parameters[1].Constants.RegisterSpace = 0;
12557     root_parameters[1].Constants.Num32BitValues = 4;
12558     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
12559     root_signature_desc.NumParameters = 2;
12560     root_signature_desc.pParameters = root_parameters;
12561     root_signature_desc.NumStaticSamplers = 0;
12562     root_signature_desc.pStaticSamplers = NULL;
12563     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
12564     hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
12565     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
12566     context.pipeline_state = create_pipeline_state(context.device,
12567             context.root_signature, desc.rt_format, &vs_color, &ps_color, NULL);
12568 
12569     transition_resource_state(command_list, context.render_target,
12570             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
12571 
12572     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
12573     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
12574     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
12575     vs_cb_color = ps_cb_color = expected_result = (struct vec4){0.0f, 1.0f, 0.0f, 1.0f};
12576     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &vs_cb_color.x, 0);
12577     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &ps_cb_color.x, 0);
12578     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
12579     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
12580     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
12581     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
12582     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
12583 
12584     transition_resource_state(command_list, context.render_target,
12585             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
12586     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_result, 0);
12587 
12588     reset_command_list(command_list, context.allocator);
12589 
12590     transition_resource_state(command_list, context.render_target,
12591             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
12592 
12593     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
12594     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
12595     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
12596     vs_cb_color = (struct vec4){0.0f, 1.0f, 0.0f, 1.0f};
12597     ps_cb_color = (struct vec4){1.0f, 1.0f, 1.0f, 1.0f};
12598     expected_result = (struct vec4){0.0f, 0.0f, 1.0f, 1.0f};
12599     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &vs_cb_color.x, 0);
12600     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &ps_cb_color.x, 0);
12601     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
12602     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
12603     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
12604     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
12605     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
12606 
12607     transition_resource_state(command_list, context.render_target,
12608             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
12609     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_result, 0);
12610 
12611     reset_command_list(command_list, context.allocator);
12612 
12613     ID3D12PipelineState_Release(context.pipeline_state);
12614     ID3D12RootSignature_Release(context.root_signature);
12615 
12616     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
12617     root_parameters[0].Constants.ShaderRegister = 1;
12618     root_parameters[0].Constants.RegisterSpace = 0;
12619     root_parameters[0].Constants.Num32BitValues = 8;
12620     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
12621     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
12622     root_parameters[1].Constants.ShaderRegister = 1;
12623     root_parameters[1].Constants.RegisterSpace = 0;
12624     root_parameters[1].Constants.Num32BitValues = 4;
12625     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
12626     root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
12627     root_parameters[2].Constants.ShaderRegister = 0;
12628     root_parameters[2].Constants.RegisterSpace = 0;
12629     root_parameters[2].Constants.Num32BitValues = 2;
12630     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
12631     root_signature_desc.NumParameters = 3;
12632     root_signature_desc.pParameters = root_parameters;
12633     root_signature_desc.NumStaticSamplers = 0;
12634     root_signature_desc.pStaticSamplers = NULL;
12635     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
12636     hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
12637     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
12638     context.pipeline_state = create_pipeline_state(context.device,
12639             context.root_signature, desc.rt_format, &vs_mix, &ps_mix, NULL);
12640 
12641     transition_resource_state(command_list, context.render_target,
12642             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
12643 
12644     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
12645     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
12646     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
12647     vs_cb_color = expected_result = (struct vec4){0.0f, 1.0f, 0.0f, 1.0f};
12648     ps_cb_color = (struct vec4){1.0f, 1.0f, 1.0f, 1.0f};
12649     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &vs_cb_color.x, 4);
12650     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &ps_cb_color.x, 0);
12651     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(command_list, 2, 0xdeadbeef, 0);
12652     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(command_list, 2, 0, 1);
12653     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
12654     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
12655     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
12656     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
12657     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
12658 
12659     transition_resource_state(command_list, context.render_target,
12660             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
12661     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_result, 0);
12662 
12663     reset_command_list(command_list, context.allocator);
12664 
12665     transition_resource_state(command_list, context.render_target,
12666             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
12667 
12668     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
12669     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
12670     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
12671     vs_cb_color = (struct vec4){0.0f, 1.0f, 0.0f, 1.0f};
12672     ps_cb_color = expected_result = (struct vec4){1.0f, 1.0f, 1.0f, 1.0f};
12673     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &vs_cb_color.x, 4);
12674     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &ps_cb_color.x, 0);
12675     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(command_list, 2, 0xdeadbeef, 0);
12676     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(command_list, 2, 1, 1);
12677     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
12678     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
12679     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
12680     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
12681     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
12682 
12683     transition_resource_state(command_list, context.render_target,
12684             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
12685     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_result, 0);
12686 
12687     reset_command_list(command_list, context.allocator);
12688 
12689     transition_resource_state(command_list, context.render_target,
12690             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
12691 
12692     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
12693     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
12694     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
12695     vs_cb_color = (struct vec4){0.5f, 1.0f, 0.5f, 1.0f};
12696     ps_cb_color = (struct vec4){0.5f, 0.7f, 1.0f, 1.0f};
12697     expected_result = (struct vec4){0.25f, 0.7f, 0.5f, 1.0f};
12698     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &vs_cb_color.x, 4);
12699     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &ps_cb_color.x, 0);
12700     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(command_list, 2, 0xdeadbeef, 0);
12701     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(command_list, 2, 2, 1);
12702     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
12703     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
12704     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
12705     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
12706     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
12707 
12708     transition_resource_state(command_list, context.render_target,
12709             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
12710     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_result, 0);
12711 
12712     destroy_test_context(&context);
12713 }
12714 
test_sample_instructions(void)12715 static void test_sample_instructions(void)
12716 {
12717     ID3D12DescriptorHeap *heap, *sampler_heap, *heaps[2];
12718     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
12719     D3D12_DESCRIPTOR_RANGE descriptor_range[2];
12720     D3D12_ROOT_PARAMETER root_parameters[3];
12721     ID3D12GraphicsCommandList *command_list;
12722     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
12723     D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
12724     D3D12_SAMPLER_DESC sampler_desc;
12725     struct test_context_desc desc;
12726     struct resource_readback rb;
12727     struct test_context context;
12728     unsigned int x_step, y_step;
12729     ID3D12CommandQueue *queue;
12730     ID3D12Resource *texture;
12731     unsigned int i, x, y;
12732     ID3D12Device *device;
12733     HRESULT hr;
12734 
12735     static const DWORD ps_sample_code[] =
12736     {
12737 #if 0
12738         Texture2D t;
12739         SamplerState s;
12740 
12741         float4 main(float4 position : SV_POSITION) : SV_Target
12742         {
12743             float2 p;
12744 
12745             p.x = position.x / 640.0f;
12746             p.y = position.y / 480.0f;
12747             return t.Sample(s, p);
12748         }
12749 #endif
12750         0x43425844, 0xd48f8d1c, 0x91689a9a, 0x99683e50, 0xae5e3efd, 0x00000001, 0x00000140, 0x00000003,
12751         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
12752         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
12753         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
12754         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000a4, 0x00000050,
12755         0x00000029, 0x0100086a, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000,
12756         0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
12757         0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002,
12758         0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x8b000045, 0x800000c2, 0x00155543, 0x001020f2,
12759         0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0100003e,
12760     };
12761     static const D3D12_SHADER_BYTECODE ps_sample = {ps_sample_code, sizeof(ps_sample_code)};
12762     static const DWORD ps_sample_b_code[] =
12763     {
12764 #if 0
12765         Texture2D t;
12766         SamplerState s;
12767 
12768         float bias;
12769 
12770         float4 main(float4 position : SV_POSITION) : SV_Target
12771         {
12772             float2 p;
12773 
12774             p.x = position.x / 640.0f;
12775             p.y = position.y / 480.0f;
12776             return t.SampleBias(s, p, bias);
12777         }
12778 #endif
12779         0x43425844, 0xc39b0686, 0x8244a7fc, 0x14c0b97a, 0x2900b3b7, 0x00000001, 0x00000150, 0x00000003,
12780         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
12781         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
12782         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
12783         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000b4, 0x00000040,
12784         0x0000002d, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000, 0x00000000,
12785         0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001,
12786         0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000,
12787         0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x0c00004a,
12788         0x001020f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000,
12789         0x0020800a, 0x00000000, 0x00000000, 0x0100003e,
12790     };
12791     static const D3D12_SHADER_BYTECODE ps_sample_b = {ps_sample_b_code, sizeof(ps_sample_b_code)};
12792     static const DWORD ps_sample_d_code[] =
12793     {
12794 #if 0
12795         Texture2D t;
12796         SamplerState s;
12797 
12798         float4 dd;
12799 
12800         float4 main(float4 position : SV_POSITION) : SV_Target
12801         {
12802             float2 p;
12803 
12804             p.x = position.x / 640.0f;
12805             p.y = position.y / 480.0f;
12806             return t.SampleGrad(s, p, float2(dd.x, dd.y), float2(dd.z, dd.w));
12807        }
12808 #endif
12809         0x43425844, 0xecc423bc, 0x3742699c, 0xf08f6dd7, 0x9976ad55, 0x00000001, 0x00000168, 0x00000003,
12810         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
12811         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
12812         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
12813         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000cc, 0x00000050,
12814         0x00000033, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000,
12815         0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000,
12816         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0a000038, 0x00100032,
12817         0x00000000, 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000,
12818         0x91000049, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46,
12819         0x00000000, 0x00106000, 0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x00208ae6, 0x00000000,
12820         0x00000000, 0x0100003e,
12821     };
12822     static const D3D12_SHADER_BYTECODE ps_sample_d = {ps_sample_d_code, sizeof(ps_sample_d_code)};
12823     static const DWORD ps_sample_l_code[] =
12824     {
12825 #if 0
12826         Texture2D t;
12827         SamplerState s;
12828 
12829         float level;
12830 
12831         float4 main(float4 position : SV_POSITION) : SV_Target
12832         {
12833             float2 p;
12834 
12835             p.x = position.x / 640.0f;
12836             p.y = position.y / 480.0f;
12837             return t.SampleLevel(s, p, level);
12838         }
12839 #endif
12840         0x43425844, 0x61e05d85, 0x2a7300fb, 0x0a83706b, 0x889d1683, 0x00000001, 0x00000150, 0x00000003,
12841         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
12842         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
12843         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
12844         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000b4, 0x00000040,
12845         0x0000002d, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000, 0x00000000,
12846         0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001,
12847         0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000,
12848         0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x0c000048,
12849         0x001020f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000,
12850         0x0020800a, 0x00000000, 0x00000000, 0x0100003e,
12851     };
12852     static const D3D12_SHADER_BYTECODE ps_sample_l = {ps_sample_l_code, sizeof(ps_sample_l_code)};
12853     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
12854     static const unsigned int r8g8b8a8_data[] =
12855     {
12856         0xff0000ff, 0xff00ffff, 0xff00ff00, 0xffffff00,
12857         0xffff0000, 0xffff00ff, 0xff000000, 0xff7f7f7f,
12858         0xffffffff, 0xffffffff, 0xffffffff, 0xff000000,
12859         0xffffffff, 0xff000000, 0xff000000, 0xff000000,
12860     };
12861     static const uint8_t a8_data[] =
12862     {
12863         0x00, 0xff, 0x7f, 0xf0,
12864         0x0f, 0x11, 0x00, 0x00,
12865         0xff, 0xf0, 0x0f, 0xff,
12866         0xfa, 0xfe, 0xaa, 0xcc,
12867     };
12868     static const unsigned int a8_expected_data[] =
12869     {
12870         0x00000000, 0xff000000, 0x7f000000, 0xf0000000,
12871         0x0f000000, 0x11000000, 0x00000000, 0x00000000,
12872         0xff000000, 0xf0000000, 0x0f000000, 0xff000000,
12873         0xfa000000, 0xfe000000, 0xaa000000, 0xcc000000,
12874     };
12875     static const unsigned int rgba_level_0[] =
12876     {
12877         0xff0000ff, 0xff00ffff, 0xff00ff00, 0xffffff00,
12878         0xffff0000, 0xffff00ff, 0xff000000, 0xff7f7f7f,
12879         0xffffffff, 0xffffffff, 0xffffffff, 0xff000000,
12880         0xffffffff, 0xff000000, 0xff000000, 0xff000000,
12881     };
12882     static const unsigned int rgba_level_1[] =
12883     {
12884         0xffffffff, 0xff0000ff,
12885         0xff000000, 0xff00ff00,
12886     };
12887     static const unsigned int rgba_level_2[] =
12888     {
12889         0xffff0000,
12890     };
12891     static const unsigned int level_1_colors[] =
12892     {
12893         0xffffffff, 0xffffffff, 0xff0000ff, 0xff0000ff,
12894         0xffffffff, 0xffffffff, 0xff0000ff, 0xff0000ff,
12895         0xff000000, 0xff000000, 0xff00ff00, 0xff00ff00,
12896         0xff000000, 0xff000000, 0xff00ff00, 0xff00ff00,
12897     };
12898     static const unsigned int level_2_colors[] =
12899     {
12900         0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000,
12901         0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000,
12902         0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000,
12903         0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000,
12904     };
12905     static const unsigned int lerp_1_2_colors[] =
12906     {
12907         0xffff7f7f, 0xffff7f7f, 0xff7f007f, 0xff7f007f,
12908         0xffff7f7f, 0xffff7f7f, 0xff7f007f, 0xff7f007f,
12909         0xff7f0000, 0xff7f0000, 0xff7f7f00, 0xff7f7f00,
12910         0xff7f0000, 0xff7f0000, 0xff7f7f00, 0xff7f7f00,
12911     };
12912     struct texture
12913     {
12914         unsigned int width;
12915         unsigned int height;
12916         unsigned int miplevel_count;
12917         unsigned int array_size;
12918         DXGI_FORMAT format;
12919         D3D12_SUBRESOURCE_DATA data[3];
12920     };
12921     static const struct texture r8g8b8a8_texture =
12922     {
12923         4, 4, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
12924         {
12925             {r8g8b8a8_data, 4 * sizeof(*r8g8b8a8_data), 16 * sizeof(*r8g8b8a8_data)},
12926         },
12927     };
12928     static const struct texture a8_texture =
12929     {
12930         4, 4, 1, 1, DXGI_FORMAT_A8_UNORM,
12931         {
12932             {a8_data, 4 * sizeof(*a8_data), 16 * sizeof(*a8_data)},
12933         },
12934     };
12935     static const struct texture rgba_texture =
12936     {
12937         4, 4, 3, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
12938         {
12939             {rgba_level_0, 4 * sizeof(*rgba_level_0), 0},
12940             {rgba_level_1, 2 * sizeof(*rgba_level_1), 0},
12941             {rgba_level_2,     sizeof(*rgba_level_2), 0},
12942         },
12943     };
12944     static const struct
12945     {
12946         const D3D12_SHADER_BYTECODE *ps_code;
12947         const struct texture *texture;
12948         D3D12_FILTER filter;
12949         float lod_bias;
12950         float min_lod;
12951         float max_lod;
12952         float ps_constants[4];
12953         const unsigned int *expected_data;
12954     }
12955     tests[] =
12956     {
12957 #define MIP_MAX      D3D12_FLOAT32_MAX
12958 #define POINT        D3D12_FILTER_MIN_MAG_MIP_POINT
12959 #define POINT_LINEAR D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR
12960         {&ps_sample,   &r8g8b8a8_texture,    POINT, 0.0f, 0.0f, MIP_MAX, {0.0f},                   r8g8b8a8_data},
12961         {&ps_sample,   &a8_texture,          POINT, 0.0f, 0.0f, MIP_MAX, {0.0f},                   a8_expected_data},
12962         {&ps_sample_b, &r8g8b8a8_texture,    POINT, 0.0f, 0.0f, MIP_MAX, {0.0f},                   r8g8b8a8_data},
12963         {&ps_sample_b, &a8_texture,          POINT, 0.0f, 0.0f, MIP_MAX, {0.0f},                   a8_expected_data},
12964         {&ps_sample_b, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {0.0f},                   rgba_level_0},
12965         {&ps_sample_b, &rgba_texture,        POINT, 8.0f, 0.0f, MIP_MAX, {0.0f},                   level_1_colors},
12966         {&ps_sample_b, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {8.0f},                   level_1_colors},
12967         {&ps_sample_b, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {8.4f},                   level_1_colors},
12968         {&ps_sample_b, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {8.5f},                   level_2_colors},
12969         {&ps_sample_b, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {9.0f},                   level_2_colors},
12970         {&ps_sample_b, &rgba_texture,        POINT, 0.0f, 0.0f, 2.0f,    {1.0f},                   rgba_level_0},
12971         {&ps_sample_b, &rgba_texture,        POINT, 0.0f, 0.0f, 2.0f,    {9.0f},                   level_2_colors},
12972         {&ps_sample_b, &rgba_texture,        POINT, 0.0f, 0.0f, 1.0f,    {9.0f},                   level_1_colors},
12973         {&ps_sample_b, &rgba_texture,        POINT, 0.0f, 0.0f, 0.0f,    {9.0f},                   rgba_level_0},
12974         {&ps_sample_d, &r8g8b8a8_texture,    POINT, 0.0f, 0.0f, MIP_MAX, {0.0f, 0.0f, 0.0f, 0.0f}, r8g8b8a8_data},
12975         {&ps_sample_d, &a8_texture,          POINT, 0.0f, 0.0f, MIP_MAX, {0.0f, 0.0f, 0.0f, 0.0f}, a8_expected_data},
12976         {&ps_sample_d, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {0.0f, 0.0f, 0.0f, 0.0f}, rgba_level_0},
12977         {&ps_sample_d, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {0.3f, 0.0f, 0.0f, 0.0f}, rgba_level_0},
12978         {&ps_sample_d, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {0.4f, 0.0f, 0.0f, 0.0f}, level_1_colors},
12979         {&ps_sample_d, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {1.0f, 0.0f, 0.0f, 0.0f}, level_2_colors},
12980         {&ps_sample_l, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {-1.0f},                  rgba_level_0},
12981         {&ps_sample_l, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {0.0f},                   rgba_level_0},
12982         {&ps_sample_l, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {0.4f},                   rgba_level_0},
12983         {&ps_sample_l, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {0.5f},                   level_1_colors},
12984         {&ps_sample_l, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {1.0f},                   level_1_colors},
12985         {&ps_sample_l, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {1.4f},                   level_1_colors},
12986         {&ps_sample_l, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {1.5f},                   level_2_colors},
12987         {&ps_sample_l, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {2.0f},                   level_2_colors},
12988         {&ps_sample_l, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {3.0f},                   level_2_colors},
12989         {&ps_sample_l, &rgba_texture,        POINT, 0.0f, 0.0f, MIP_MAX, {4.0f},                   level_2_colors},
12990         {&ps_sample_l, &rgba_texture, POINT_LINEAR, 0.0f, 0.0f, MIP_MAX, {1.5f},                   lerp_1_2_colors},
12991         {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {-2.0f},                  rgba_level_0},
12992         {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {-1.0f},                  level_1_colors},
12993         {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {0.0f},                   level_2_colors},
12994         {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {1.0f},                   level_2_colors},
12995         {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 0.0f, MIP_MAX, {1.5f},                   level_2_colors},
12996         {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 2.0f, 2.0f,    {-9.0f},                  level_2_colors},
12997         {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 2.0f, 2.0f,    {-1.0f},                  level_2_colors},
12998         {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 2.0f, 2.0f,    {0.0f},                   level_2_colors},
12999         {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 2.0f, 2.0f,    {1.0f},                   level_2_colors},
13000         {&ps_sample_l, &rgba_texture, POINT_LINEAR, 2.0f, 2.0f, 2.0f,    {9.0f},                   level_2_colors},
13001         {&ps_sample_l, &rgba_texture,        POINT, 2.0f, 2.0f, 2.0f,    {-9.0f},                  level_2_colors},
13002         {&ps_sample_l, &rgba_texture,        POINT, 2.0f, 2.0f, 2.0f,    {-1.0f},                  level_2_colors},
13003         {&ps_sample_l, &rgba_texture,        POINT, 2.0f, 2.0f, 2.0f,    {0.0f},                   level_2_colors},
13004         {&ps_sample_l, &rgba_texture,        POINT, 2.0f, 2.0f, 2.0f,    {1.0f},                   level_2_colors},
13005         {&ps_sample_l, &rgba_texture,        POINT, 2.0f, 2.0f, 2.0f,    {9.0f},                   level_2_colors},
13006 #undef MIP_MAX
13007 #undef POINT
13008 #undef POINT_LINEAR
13009     };
13010 
13011     memset(&desc, 0, sizeof(desc));
13012     desc.rt_width = 640;
13013     desc.rt_height = 480;
13014     desc.no_root_signature = true;
13015     if (!init_test_context(&context, &desc))
13016         return;
13017     device = context.device;
13018     command_list = context.list;
13019     queue = context.queue;
13020 
13021     descriptor_range[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
13022     descriptor_range[0].NumDescriptors = 1;
13023     descriptor_range[0].BaseShaderRegister = 0;
13024     descriptor_range[0].RegisterSpace = 0;
13025     descriptor_range[0].OffsetInDescriptorsFromTableStart = 0;
13026     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
13027     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
13028     root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_range[0];
13029     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
13030 
13031     descriptor_range[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
13032     descriptor_range[1].NumDescriptors = 1;
13033     descriptor_range[1].BaseShaderRegister = 0;
13034     descriptor_range[1].RegisterSpace = 0;
13035     descriptor_range[1].OffsetInDescriptorsFromTableStart = 0;
13036     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
13037     root_parameters[1].DescriptorTable.NumDescriptorRanges = 1;
13038     root_parameters[1].DescriptorTable.pDescriptorRanges = &descriptor_range[1];
13039     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
13040 
13041     root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
13042     root_parameters[2].Constants.ShaderRegister = 0;
13043     root_parameters[2].Constants.RegisterSpace = 0;
13044     root_parameters[2].Constants.Num32BitValues = ARRAY_SIZE(tests->ps_constants);
13045     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
13046 
13047     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
13048     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
13049     root_signature_desc.pParameters = root_parameters;
13050     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
13051     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
13052 
13053     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
13054     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
13055     gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
13056 
13057     sampler_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 1);
13058 
13059     for (i = 0; i < ARRAY_SIZE(tests); ++i)
13060     {
13061         vkd3d_test_set_context("Test %u", i);
13062 
13063         memset(&sampler_desc, 0, sizeof(sampler_desc));
13064         sampler_desc.Filter = tests[i].filter;
13065         sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
13066         sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
13067         sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
13068         sampler_desc.MipLODBias = tests[i].lod_bias;
13069         sampler_desc.MinLOD = tests[i].min_lod;
13070         sampler_desc.MaxLOD = tests[i].max_lod;
13071         ID3D12Device_CreateSampler(device, &sampler_desc, get_cpu_sampler_handle(&context, sampler_heap, 0));
13072 
13073         if (context.pipeline_state)
13074             ID3D12PipelineState_Release(context.pipeline_state);
13075         context.pipeline_state = create_pipeline_state(device, context.root_signature,
13076                 context.render_target_desc.Format, NULL, tests[i].ps_code, NULL);
13077 
13078         texture = create_default_texture2d(device, tests[i].texture->width, tests[i].texture->height,
13079                 tests[i].texture->array_size, tests[i].texture->miplevel_count, tests[i].texture->format,
13080                 D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
13081         upload_texture_data(texture, tests[i].texture->data,
13082                 tests[i].texture->miplevel_count * tests[i].texture->array_size, queue, command_list);
13083         reset_command_list(command_list, context.allocator);
13084         transition_resource_state(command_list, texture,
13085                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
13086 
13087         ID3D12Device_CreateShaderResourceView(device, texture, NULL, cpu_handle);
13088 
13089         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
13090 
13091         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
13092         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
13093         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
13094         heaps[0] = heap; heaps[1] = sampler_heap;
13095         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, ARRAY_SIZE(heaps), heaps);
13096         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
13097         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 1,
13098                 get_gpu_sampler_handle(&context, sampler_heap, 0));
13099         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
13100         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
13101         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
13102         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 2,
13103                 ARRAY_SIZE(tests[i].ps_constants), tests[i].ps_constants, 0);
13104         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
13105 
13106         transition_resource_state(command_list, context.render_target,
13107                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
13108 
13109         x_step = desc.rt_width / tests[i].texture->width;
13110         y_step = desc.rt_height / tests[i].texture->height;
13111         get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
13112         for (y = 0; y < tests[i].texture->height; ++y)
13113         {
13114             for (x = 0; x < tests[i].texture->width; ++x)
13115             {
13116                 unsigned int color = get_readback_uint(&rb, x * x_step + x_step / 2, y * y_step + y_step / 2, 0);
13117                 ok(compare_color(color, tests[i].expected_data[tests[i].texture->width * y + x], 1),
13118                         "Got color 0x%08x, expected 0x%08x at (%u, %u).\n",
13119                         color, tests[i].expected_data[tests[i].texture->width * y + x], x, y);
13120             }
13121         }
13122         release_resource_readback(&rb);
13123 
13124         ID3D12Resource_Release(texture);
13125         reset_command_list(command_list, context.allocator);
13126         transition_resource_state(command_list, context.render_target,
13127                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
13128     }
13129     vkd3d_test_set_context(NULL);
13130 
13131     ID3D12DescriptorHeap_Release(heap);
13132     ID3D12DescriptorHeap_Release(sampler_heap);
13133     destroy_test_context(&context);
13134 }
13135 
test_texture_ld(void)13136 static void test_texture_ld(void)
13137 {
13138     ID3D12GraphicsCommandList *command_list;
13139     D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
13140     struct test_context_desc desc;
13141     struct test_context context;
13142     ID3D12DescriptorHeap *heap;
13143     ID3D12CommandQueue *queue;
13144     ID3D12Resource *texture;
13145     unsigned int i;
13146 
13147     static const DWORD ps_ld_code[] =
13148     {
13149 #if 0
13150         Texture2D t;
13151 
13152         int2 offset;
13153         uint2 location;
13154 
13155         float4 main() : SV_Target
13156         {
13157             switch (offset.x)
13158             {
13159                 case -1:
13160                     switch (offset.y)
13161                     {
13162                         case -2: return t.Load(uint3(location, 0), int2(-1, -2));
13163                         case -1: return t.Load(uint3(location, 0), int2(-1, -1));
13164                         case  0: return t.Load(uint3(location, 0), int2(-1,  0));
13165                         case  1: return t.Load(uint3(location, 0), int2(-1,  1));
13166                         case  2: return t.Load(uint3(location, 0), int2(-1,  2));
13167                     }
13168                     break;
13169                 case 0:
13170                     switch (offset.y)
13171                     {
13172                         case -2: return t.Load(uint3(location, 0), int2(0, -2));
13173                         case -1: return t.Load(uint3(location, 0), int2(0, -1));
13174                         case  0: return t.Load(uint3(location, 0), int2(0,  0));
13175                         case  1: return t.Load(uint3(location, 0), int2(0,  1));
13176                         case  2: return t.Load(uint3(location, 0), int2(0,  2));
13177                     }
13178                     break;
13179                 case 1:
13180                     switch (offset.y)
13181                     {
13182                         case -2: return t.Load(uint3(location, 0), int2(1, -2));
13183                         case -1: return t.Load(uint3(location, 0), int2(1, -1));
13184                         case  0: return t.Load(uint3(location, 0), int2(1,  0));
13185                         case  1: return t.Load(uint3(location, 0), int2(1,  1));
13186                         case  2: return t.Load(uint3(location, 0), int2(1,  2));
13187                     }
13188                     break;
13189             }
13190 
13191             return t.Load(uint3(location, 0));
13192         }
13193 #endif
13194         0x43425844, 0xe925cc02, 0x43ea9623, 0xb67c6425, 0xb4503305, 0x00000001, 0x00000844, 0x00000003,
13195         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
13196         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
13197         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000007cc, 0x00000050, 0x000001f3,
13198         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04001858, 0x00107000, 0x00000000,
13199         0x00005555, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0400004c, 0x0020800a,
13200         0x00000000, 0x00000000, 0x03000006, 0x00004001, 0xffffffff, 0x0400004c, 0x0020801a, 0x00000000,
13201         0x00000000, 0x03000006, 0x00004001, 0xfffffffe, 0x06000036, 0x00100032, 0x00000000, 0x00208ae6,
13202         0x00000000, 0x00000000, 0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
13203         0x00000000, 0x00000000, 0x8a00002d, 0x8001de01, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000,
13204         0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0100003e, 0x03000006, 0x00004001, 0xffffffff,
13205         0x06000036, 0x00100032, 0x00000000, 0x00208ae6, 0x00000000, 0x00000000, 0x08000036, 0x001000c2,
13206         0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8a00002d, 0x8001fe01,
13207         0x800000c2, 0x00155543, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000,
13208         0x0100003e, 0x03000006, 0x00004001, 0x00000000, 0x06000036, 0x00100032, 0x00000000, 0x00208ae6,
13209         0x00000000, 0x00000000, 0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
13210         0x00000000, 0x00000000, 0x8a00002d, 0x80001e01, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000,
13211         0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0100003e, 0x03000006, 0x00004001, 0x00000001,
13212         0x06000036, 0x00100032, 0x00000000, 0x00208ae6, 0x00000000, 0x00000000, 0x08000036, 0x001000c2,
13213         0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8a00002d, 0x80003e01,
13214         0x800000c2, 0x00155543, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000,
13215         0x0100003e, 0x03000006, 0x00004001, 0x00000002, 0x06000036, 0x00100032, 0x00000000, 0x00208ae6,
13216         0x00000000, 0x00000000, 0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
13217         0x00000000, 0x00000000, 0x8a00002d, 0x80005e01, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000,
13218         0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0100003e, 0x0100000a, 0x01000002, 0x01000017,
13219         0x01000002, 0x03000006, 0x00004001, 0x00000000, 0x0400004c, 0x0020801a, 0x00000000, 0x00000000,
13220         0x03000006, 0x00004001, 0xfffffffe, 0x06000036, 0x00100032, 0x00000000, 0x00208ae6, 0x00000000,
13221         0x00000000, 0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
13222         0x00000000, 0x8a00002d, 0x8001c001, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000, 0x00100e46,
13223         0x00000000, 0x00107e46, 0x00000000, 0x0100003e, 0x03000006, 0x00004001, 0xffffffff, 0x06000036,
13224         0x00100032, 0x00000000, 0x00208ae6, 0x00000000, 0x00000000, 0x08000036, 0x001000c2, 0x00000000,
13225         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8a00002d, 0x8001e001, 0x800000c2,
13226         0x00155543, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0100003e,
13227         0x03000006, 0x00004001, 0x00000000, 0x06000036, 0x00100032, 0x00000000, 0x00208ae6, 0x00000000,
13228         0x00000000, 0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
13229         0x00000000, 0x8900002d, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
13230         0x00107e46, 0x00000000, 0x0100003e, 0x03000006, 0x00004001, 0x00000001, 0x06000036, 0x00100032,
13231         0x00000000, 0x00208ae6, 0x00000000, 0x00000000, 0x08000036, 0x001000c2, 0x00000000, 0x00004002,
13232         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8a00002d, 0x80002001, 0x800000c2, 0x00155543,
13233         0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0100003e, 0x03000006,
13234         0x00004001, 0x00000002, 0x06000036, 0x00100032, 0x00000000, 0x00208ae6, 0x00000000, 0x00000000,
13235         0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
13236         0x8a00002d, 0x80004001, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
13237         0x00107e46, 0x00000000, 0x0100003e, 0x0100000a, 0x01000002, 0x01000017, 0x01000002, 0x03000006,
13238         0x00004001, 0x00000001, 0x0400004c, 0x0020801a, 0x00000000, 0x00000000, 0x03000006, 0x00004001,
13239         0xfffffffe, 0x06000036, 0x00100032, 0x00000000, 0x00208ae6, 0x00000000, 0x00000000, 0x08000036,
13240         0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8a00002d,
13241         0x8001c201, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46,
13242         0x00000000, 0x0100003e, 0x03000006, 0x00004001, 0xffffffff, 0x06000036, 0x00100032, 0x00000000,
13243         0x00208ae6, 0x00000000, 0x00000000, 0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000,
13244         0x00000000, 0x00000000, 0x00000000, 0x8a00002d, 0x8001e201, 0x800000c2, 0x00155543, 0x001020f2,
13245         0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0100003e, 0x03000006, 0x00004001,
13246         0x00000000, 0x06000036, 0x00100032, 0x00000000, 0x00208ae6, 0x00000000, 0x00000000, 0x08000036,
13247         0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8a00002d,
13248         0x80000201, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46,
13249         0x00000000, 0x0100003e, 0x03000006, 0x00004001, 0x00000001, 0x06000036, 0x00100032, 0x00000000,
13250         0x00208ae6, 0x00000000, 0x00000000, 0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000,
13251         0x00000000, 0x00000000, 0x00000000, 0x8a00002d, 0x80002201, 0x800000c2, 0x00155543, 0x001020f2,
13252         0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0100003e, 0x03000006, 0x00004001,
13253         0x00000002, 0x06000036, 0x00100032, 0x00000000, 0x00208ae6, 0x00000000, 0x00000000, 0x08000036,
13254         0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8a00002d,
13255         0x80004201, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46,
13256         0x00000000, 0x0100003e, 0x0100000a, 0x01000002, 0x01000017, 0x01000002, 0x0100000a, 0x01000002,
13257         0x01000017, 0x06000036, 0x00100032, 0x00000000, 0x00208ae6, 0x00000000, 0x00000000, 0x08000036,
13258         0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8900002d,
13259         0x800000c2, 0x00155543, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000,
13260         0x0100003e,
13261     };
13262     static const D3D12_SHADER_BYTECODE ps_ld = {ps_ld_code, sizeof(ps_ld_code)};
13263     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
13264     static const unsigned int texture_data[] =
13265     {
13266         0xff0008ff, 0xff00ffff, 0xff00ff05, 0xffffff01,
13267         0xffff0007, 0xffff00ff, 0x11111101, 0xff7f7f7f,
13268         0x44444f44, 0x88888888, 0x22222222, 0xff000002,
13269         0x66f66666, 0xff000000, 0xff000003, 0x55555555,
13270     };
13271     static const D3D12_SUBRESOURCE_DATA resource_data = {&texture_data, sizeof(texture_data) / 4};
13272     static const struct
13273     {
13274         int32_t constants[4];
13275         unsigned int expected_color;
13276     }
13277     tests[] =
13278     {
13279         {{ 0,  0, 0, 0}, 0xff0008ff},
13280         {{ 1,  0, 0, 0}, 0xff00ffff},
13281         {{ 0,  1, 0, 0}, 0xffff0007},
13282         {{ 1,  1, 0, 0}, 0xffff00ff},
13283         {{ 3,  3, 0, 0}, 0xff0008ff},
13284         {{ 3,  3, 1, 1}, 0xffff00ff},
13285         {{ 0,  0, 3, 3}, 0x55555555},
13286         {{-1, -1, 3, 3}, 0x22222222},
13287         {{-1, -2, 3, 3}, 0x11111101},
13288         {{ 0, -1, 3, 3}, 0xff000002},
13289         {{ 0, -2, 3, 3}, 0xff7f7f7f},
13290         {{ 3,  3, 3, 3}, 0x55555555},
13291     };
13292 
13293     if (use_warp_device)
13294     {
13295         skip("WARP device is removed when ps_ld is used.\n");
13296         return;
13297     }
13298 
13299     memset(&desc, 0, sizeof(desc));
13300     desc.no_root_signature = true;
13301     if (!init_test_context(&context, &desc))
13302         return;
13303     command_list = context.list;
13304     queue = context.queue;
13305 
13306     context.root_signature = create_texture_root_signature(context.device,
13307             D3D12_SHADER_VISIBILITY_PIXEL, 4, 0);
13308     context.pipeline_state = create_pipeline_state(context.device,
13309             context.root_signature, context.render_target_desc.Format, NULL, &ps_ld, NULL);
13310 
13311     heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
13312     gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
13313 
13314     texture = create_default_texture(context.device,
13315             4, 4, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D12_RESOURCE_STATE_COPY_DEST);
13316     upload_texture_data(texture, &resource_data, 1, queue, command_list);
13317     reset_command_list(command_list, context.allocator);
13318     transition_resource_state(command_list, texture,
13319             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
13320     ID3D12Device_CreateShaderResourceView(context.device, texture, NULL,
13321             ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap));
13322 
13323     for (i = 0; i < ARRAY_SIZE(tests); ++i)
13324     {
13325         vkd3d_test_set_context("Test %u", i);
13326 
13327         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
13328 
13329         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
13330         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
13331         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
13332         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
13333         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
13334         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
13335         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
13336         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
13337         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1,
13338                 ARRAY_SIZE(tests[i].constants), &tests[i].constants, 0);
13339         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
13340 
13341         transition_resource_state(command_list, context.render_target,
13342                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
13343         check_sub_resource_uint(context.render_target, 0, queue, command_list, tests[i].expected_color, 0);
13344 
13345         reset_command_list(command_list, context.allocator);
13346         transition_resource_state(command_list, context.render_target,
13347                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
13348     }
13349     vkd3d_test_set_context(NULL);
13350 
13351     ID3D12Resource_Release(texture);
13352     ID3D12DescriptorHeap_Release(heap);
13353     destroy_test_context(&context);
13354 }
13355 
test_gather(void)13356 static void test_gather(void)
13357 {
13358     struct
13359     {
13360         int width, height;
13361         int offset_x, offset_y;
13362     } constants;
13363 
13364     ID3D12GraphicsCommandList *command_list;
13365     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
13366     D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
13367     struct test_context_desc desc;
13368     struct resource_readback rb;
13369     struct test_context context;
13370     ID3D12DescriptorHeap *heap;
13371     ID3D12CommandQueue *queue;
13372     ID3D12Resource *texture;
13373     unsigned int x, y;
13374 
13375     static const DWORD gather4_code[] =
13376     {
13377 #if 0
13378         SamplerState s;
13379         Texture2D<float4> t;
13380 
13381         int2 size;
13382 
13383         float4 main(float4 position : SV_Position) : SV_Target
13384         {
13385             return t.Gather(s, position.xy / size);
13386         }
13387 #endif
13388         0x43425844, 0xca1ee692, 0xb122f477, 0x8c467d38, 0x0f5a233a, 0x00000001, 0x00000154, 0x00000003,
13389         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
13390         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
13391         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
13392         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000b8, 0x00000041,
13393         0x0000002e, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000,
13394         0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000,
13395         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0600002b, 0x00100032,
13396         0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x0700000e, 0x00100032, 0x00000000, 0x00101046,
13397         0x00000000, 0x00100046, 0x00000000, 0x0900006d, 0x001020f2, 0x00000000, 0x00100046, 0x00000000,
13398         0x00107e46, 0x00000000, 0x0010600a, 0x00000000, 0x0100003e,
13399     };
13400     static const D3D12_SHADER_BYTECODE ps_gather4 = {gather4_code, sizeof(gather4_code)};
13401     static const DWORD gather4_offset_code[] =
13402     {
13403 #if 0
13404         SamplerState s;
13405         Texture2D<float4> t;
13406 
13407         int2 size;
13408 
13409         float4 main(float4 position : SV_Position) : SV_Target
13410         {
13411             return t.Gather(s, position.xy / size, int2(1, 1));
13412         }
13413 #endif
13414         0x43425844, 0xe5ab2216, 0x90748ece, 0x7ccf2123, 0x4edbba7c, 0x00000001, 0x00000158, 0x00000003,
13415         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
13416         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
13417         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
13418         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000bc, 0x00000041,
13419         0x0000002f, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000,
13420         0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000,
13421         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0600002b, 0x00100032,
13422         0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x0700000e, 0x00100032, 0x00000000, 0x00101046,
13423         0x00000000, 0x00100046, 0x00000000, 0x8a00006d, 0x00002201, 0x001020f2, 0x00000000, 0x00100046,
13424         0x00000000, 0x00107e46, 0x00000000, 0x0010600a, 0x00000000, 0x0100003e,
13425     };
13426     static const D3D12_SHADER_BYTECODE ps_gather4_offset = {gather4_offset_code, sizeof(gather4_offset_code)};
13427     static const DWORD gather4_green_code[] =
13428     {
13429 #if 0
13430         SamplerState s;
13431         Texture2D<float4> t;
13432 
13433         int2 size;
13434 
13435         float4 main(float4 position : SV_Position) : SV_Target
13436         {
13437             return t.GatherGreen(s, position.xy / size);
13438         }
13439 #endif
13440         0x43425844, 0x2b0ad2d9, 0x8ad30b52, 0xc418477f, 0xe5211693, 0x00000001, 0x0000015c, 0x00000003,
13441         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
13442         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
13443         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
13444         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000c0, 0x00000050,
13445         0x00000030, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000,
13446         0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000,
13447         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0600002b, 0x00100032,
13448         0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x0700000e, 0x00100032, 0x00000000, 0x00101046,
13449         0x00000000, 0x00100046, 0x00000000, 0x8b00006d, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000,
13450         0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x0010601a, 0x00000000, 0x0100003e,
13451     };
13452     static const D3D12_SHADER_BYTECODE ps_gather4_green = {gather4_green_code, sizeof(gather4_green_code)};
13453     static const DWORD gather4_po_code[] =
13454     {
13455 #if 0
13456         SamplerState s;
13457         Texture2D<float4> t;
13458 
13459         int2 size;
13460         int2 offset;
13461 
13462         float4 main(float4 position : SV_Position) : SV_Target
13463         {
13464             return t.Gather(s, position.xy / size, offset);
13465         }
13466 #endif
13467         0x43425844, 0xe19bdd35, 0x44514fb3, 0xfaa8727f, 0xc1092da0, 0x00000001, 0x00000168, 0x00000003,
13468         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
13469         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
13470         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
13471         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000cc, 0x00000050,
13472         0x00000033, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000,
13473         0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000,
13474         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0600002b, 0x00100032,
13475         0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x0700000e, 0x00100032, 0x00000000, 0x00101046,
13476         0x00000000, 0x00100046, 0x00000000, 0x8e00007f, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000,
13477         0x00100046, 0x00000000, 0x00208ae6, 0x00000000, 0x00000000, 0x00107e46, 0x00000000, 0x0010600a,
13478         0x00000000, 0x0100003e,
13479     };
13480     static const D3D12_SHADER_BYTECODE ps_gather4_po = {gather4_po_code, sizeof(gather4_po_code)};
13481     static const struct vec4 texture_data[] =
13482     {
13483         {0.0f, 0.0f}, {1.0f, 1.0f}, {2.0f, 2.0f}, {3.0f, 3.0f},
13484         {4.0f, 0.1f}, {5.0f, 1.1f}, {6.0f, 2.1f}, {7.0f, 3.1f},
13485         {8.0f, 0.2f}, {9.0f, 1.2f}, {0.5f, 2.2f}, {1.5f, 3.2f},
13486         {2.5f, 0.3f}, {3.5f, 1.3f}, {4.5f, 2.3f}, {5.5f, 3.3f},
13487     };
13488     static const struct vec4 expected_gather4[] =
13489     {
13490         {4.0f, 5.0f, 1.0f, 0.0f}, {5.0f, 6.0f, 2.0f, 1.0f}, {6.0f, 7.0f, 3.0f, 2.0f}, {7.0f, 7.0f, 3.0f, 3.0f},
13491         {8.0f, 9.0f, 5.0f, 4.0f}, {9.0f, 0.5f, 6.0f, 5.0f}, {0.5f, 1.5f, 7.0f, 6.0f}, {1.5f, 1.5f, 7.0f, 7.0f},
13492         {2.5f, 3.5f, 9.0f, 8.0f}, {3.5f, 4.5f, 0.5f, 9.0f}, {4.5f, 5.5f, 1.5f, 0.5f}, {5.5f, 5.5f, 1.5f, 1.5f},
13493         {2.5f, 3.5f, 3.5f, 2.5f}, {3.5f, 4.5f, 4.5f, 3.5f}, {4.5f, 5.5f, 5.5f, 4.5f}, {5.5f, 5.5f, 5.5f, 5.5f},
13494     };
13495     static const struct vec4 expected_gather4_offset[] =
13496     {
13497         {9.0f, 0.5f, 6.0f, 5.0f}, {0.5f, 1.5f, 7.0f, 6.0f}, {1.5f, 1.5f, 7.0f, 7.0f}, {1.5f, 1.5f, 7.0f, 7.0f},
13498         {3.5f, 4.5f, 0.5f, 9.0f}, {4.5f, 5.5f, 1.5f, 0.5f}, {5.5f, 5.5f, 1.5f, 1.5f}, {5.5f, 5.5f, 1.5f, 1.5f},
13499         {3.5f, 4.5f, 4.5f, 3.5f}, {4.5f, 5.5f, 5.5f, 4.5f}, {5.5f, 5.5f, 5.5f, 5.5f}, {5.5f, 5.5f, 5.5f, 5.5f},
13500         {3.5f, 4.5f, 4.5f, 3.5f}, {4.5f, 5.5f, 5.5f, 4.5f}, {5.5f, 5.5f, 5.5f, 5.5f}, {5.5f, 5.5f, 5.5f, 5.5f},
13501     };
13502     static const struct vec4 expected_gather4_green[] =
13503     {
13504         {0.1f, 1.1f, 1.0f, 0.0f}, {1.1f, 2.1f, 2.0f, 1.0f}, {2.1f, 3.1f, 3.0f, 2.0f}, {3.1f, 3.1f, 3.0f, 3.0f},
13505         {0.2f, 1.2f, 1.1f, 0.1f}, {1.2f, 2.2f, 2.1f, 1.1f}, {2.2f, 3.2f, 3.1f, 2.1f}, {3.2f, 3.2f, 3.1f, 3.1f},
13506         {0.3f, 1.3f, 1.2f, 0.2f}, {1.3f, 2.3f, 2.2f, 1.2f}, {2.3f, 3.3f, 3.2f, 2.2f}, {3.3f, 3.3f, 3.2f, 3.2f},
13507         {0.3f, 1.3f, 1.3f, 0.3f}, {1.3f, 2.3f, 2.3f, 1.3f}, {2.3f, 3.3f, 3.3f, 2.3f}, {3.3f, 3.3f, 3.3f, 3.3f},
13508     };
13509     static const struct vec4 white = {1.0f, 1.0f, 1.0f, 1.0f};
13510     static const D3D12_SUBRESOURCE_DATA resource_data = {&texture_data, sizeof(texture_data) / 4};
13511 
13512     memset(&desc, 0, sizeof(desc));
13513     desc.rt_width = 4;
13514     desc.rt_height = 4;
13515     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
13516     desc.no_root_signature = true;
13517     if (!init_test_context(&context, &desc))
13518         return;
13519     command_list = context.list;
13520     queue = context.queue;
13521 
13522     context.root_signature = create_texture_root_signature(context.device,
13523             D3D12_SHADER_VISIBILITY_PIXEL, 4, 0);
13524 
13525     heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
13526     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
13527     gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
13528 
13529     texture = create_default_texture(context.device, 4, 4, DXGI_FORMAT_R32G32B32A32_FLOAT,
13530             0, D3D12_RESOURCE_STATE_COPY_DEST);
13531     ID3D12Device_CreateShaderResourceView(context.device, texture, NULL, cpu_handle);
13532     upload_texture_data(texture, &resource_data, 1, queue, command_list);
13533     reset_command_list(command_list, context.allocator);
13534     transition_resource_state(command_list, texture,
13535             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
13536 
13537     constants.width = 4;
13538     constants.height = 4;
13539     constants.offset_x = 1;
13540     constants.offset_y = 1;
13541 
13542     /* ps_gather4 */
13543     context.pipeline_state = create_pipeline_state(context.device,
13544             context.root_signature, desc.rt_format, NULL, &ps_gather4, NULL);
13545 
13546     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
13547 
13548     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
13549     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
13550     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
13551     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
13552     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
13553     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &constants.width, 0);
13554     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
13555     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
13556     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
13557     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
13558 
13559     transition_resource_state(command_list, context.render_target,
13560             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
13561     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
13562     for (y = 0; y < rb.height; ++y)
13563     {
13564         for (x = 0; x < rb.width; ++x)
13565         {
13566             const struct vec4 *expected = &expected_gather4[y * rb.width + x];
13567             const struct vec4 *got = get_readback_vec4(&rb, x, y);
13568             ok(compare_vec4(got, expected, 0),
13569                     "Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
13570                     got->x, got->y, got->z, got->w, expected->x, expected->y, expected->z, expected->w);
13571         }
13572     }
13573     release_resource_readback(&rb);
13574 
13575     ID3D12PipelineState_Release(context.pipeline_state);
13576     reset_command_list(command_list, context.allocator);
13577     transition_resource_state(command_list, context.render_target,
13578             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
13579 
13580     /* ps_gather4_offset */
13581     context.pipeline_state = create_pipeline_state(context.device,
13582             context.root_signature, desc.rt_format, NULL, &ps_gather4_offset, NULL);
13583 
13584     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
13585 
13586     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
13587     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
13588     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
13589     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
13590     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
13591     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &constants.width, 0);
13592     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
13593     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
13594     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
13595     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
13596 
13597     transition_resource_state(command_list, context.render_target,
13598             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
13599     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
13600     for (y = 0; y < rb.height; ++y)
13601     {
13602         for (x = 0; x < rb.width; ++x)
13603         {
13604             const struct vec4 *expected = &expected_gather4_offset[y * rb.width + x];
13605             const struct vec4 *got = get_readback_vec4(&rb, x, y);
13606             ok(compare_vec4(got, expected, 0),
13607                     "Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
13608                     got->x, got->y, got->z, got->w, expected->x, expected->y, expected->z, expected->w);
13609         }
13610     }
13611     release_resource_readback(&rb);
13612 
13613     ID3D12PipelineState_Release(context.pipeline_state);
13614     reset_command_list(command_list, context.allocator);
13615     transition_resource_state(command_list, context.render_target,
13616             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
13617 
13618     /* ps_gather4_green */
13619     context.pipeline_state = create_pipeline_state(context.device,
13620             context.root_signature, desc.rt_format, NULL, &ps_gather4_green, NULL);
13621 
13622     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
13623 
13624     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
13625     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
13626     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
13627     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
13628     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
13629     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &constants.width, 0);
13630     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
13631     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
13632     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
13633     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
13634 
13635     transition_resource_state(command_list, context.render_target,
13636             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
13637     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
13638     for (y = 0; y < rb.height; ++y)
13639     {
13640         for (x = 0; x < rb.width; ++x)
13641         {
13642             const struct vec4 *expected = &expected_gather4_green[y * rb.width + x];
13643             const struct vec4 *got = get_readback_vec4(&rb, x, y);
13644             ok(compare_vec4(got, expected, 0),
13645                     "Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
13646                     got->x, got->y, got->z, got->w, expected->x, expected->y, expected->z, expected->w);
13647         }
13648     }
13649     release_resource_readback(&rb);
13650 
13651     ID3D12PipelineState_Release(context.pipeline_state);
13652     reset_command_list(command_list, context.allocator);
13653     transition_resource_state(command_list, context.render_target,
13654             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
13655 
13656     /* ps_gather4_po */
13657     context.pipeline_state = create_pipeline_state(context.device,
13658             context.root_signature, desc.rt_format, NULL, &ps_gather4_po, NULL);
13659 
13660     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
13661 
13662     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
13663     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
13664     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
13665     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
13666     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
13667     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &constants.width, 0);
13668     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
13669     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
13670     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
13671     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
13672 
13673     transition_resource_state(command_list, context.render_target,
13674             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
13675     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
13676     for (y = 0; y < rb.height; ++y)
13677     {
13678         for (x = 0; x < rb.width; ++x)
13679         {
13680             const struct vec4 *expected = &expected_gather4_offset[y * rb.width + x];
13681             const struct vec4 *got = get_readback_vec4(&rb, x, y);
13682             ok(compare_vec4(got, expected, 0),
13683                     "Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
13684                     got->x, got->y, got->z, got->w, expected->x, expected->y, expected->z, expected->w);
13685         }
13686     }
13687     release_resource_readback(&rb);
13688 
13689     reset_command_list(command_list, context.allocator);
13690     transition_resource_state(command_list, context.render_target,
13691             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
13692 
13693     constants.offset_x = 0;
13694     constants.offset_y = 0;
13695 
13696     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
13697 
13698     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
13699     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
13700     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
13701     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
13702     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
13703     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &constants.width, 0);
13704     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
13705     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
13706     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
13707     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
13708 
13709     transition_resource_state(command_list, context.render_target,
13710             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
13711     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
13712     for (y = 0; y < rb.height; ++y)
13713     {
13714         for (x = 0; x < rb.width; ++x)
13715         {
13716             const struct vec4 *expected = &expected_gather4[y * rb.width + x];
13717             const struct vec4 *got = get_readback_vec4(&rb, x, y);
13718             ok(compare_vec4(got, expected, 0),
13719                     "Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
13720                     got->x, got->y, got->z, got->w, expected->x, expected->y, expected->z, expected->w);
13721         }
13722     }
13723     release_resource_readback(&rb);
13724 
13725     ID3D12Resource_Release(texture);
13726     ID3D12DescriptorHeap_Release(heap);
13727     destroy_test_context(&context);
13728 }
13729 
test_gather_c(void)13730 static void test_gather_c(void)
13731 {
13732     struct
13733     {
13734         int width, height;
13735         int offset_x, offset_y;
13736         float d_ref;
13737     } constants;
13738 
13739     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
13740     ID3D12GraphicsCommandList *command_list;
13741     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
13742     D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
13743     struct test_context_desc desc;
13744     struct resource_readback rb;
13745     struct test_context context;
13746     ID3D12DescriptorHeap *heap;
13747     ID3D12CommandQueue *queue;
13748     ID3D12Resource *texture;
13749     unsigned int x, y;
13750 
13751     static const DWORD gather4_c_code[] =
13752     {
13753 #if 0
13754         SamplerComparisonState s;
13755         Texture2D<float4> t;
13756 
13757         int2 size;
13758         int2 offset;
13759         float d_ref;
13760 
13761         float4 main(float4 position : SV_Position) : SV_Target
13762         {
13763             return t.GatherCmp(s, position.xy / size, d_ref);
13764         }
13765 #endif
13766         0x43425844, 0xd3d04479, 0x901e9208, 0x7074fd0c, 0xbcadb2da, 0x00000001, 0x00000168, 0x00000003,
13767         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
13768         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
13769         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
13770         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000cc, 0x00000050,
13771         0x00000033, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0300085a, 0x00106000,
13772         0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000,
13773         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0600002b, 0x00100032,
13774         0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x0700000e, 0x00100032, 0x00000000, 0x00101046,
13775         0x00000000, 0x00100046, 0x00000000, 0x8e00007e, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000,
13776         0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x0010600a, 0x00000000, 0x0020800a, 0x00000000,
13777         0x00000001, 0x0100003e,
13778     };
13779     static const D3D12_SHADER_BYTECODE ps_gather4_c = {gather4_c_code, sizeof(gather4_c_code)};
13780     static const DWORD gather4_po_c_code[] =
13781     {
13782 #if 0
13783         SamplerComparisonState s;
13784         Texture2D<float4> t;
13785 
13786         int2 size;
13787         int2 offset;
13788         float d_ref;
13789 
13790         float4 main(float4 position : SV_Position) : SV_Target
13791         {
13792             return t.GatherCmp(s, position.xy / size, d_ref, offset);
13793         }
13794 #endif
13795         0x43425844, 0x501de13e, 0x472d2d20, 0x6df0fee4, 0xef27d9e6, 0x00000001, 0x00000174, 0x00000003,
13796         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
13797         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
13798         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
13799         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000d8, 0x00000050,
13800         0x00000036, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0300085a, 0x00106000,
13801         0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000,
13802         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0600002b, 0x00100032,
13803         0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x0700000e, 0x00100032, 0x00000000, 0x00101046,
13804         0x00000000, 0x00100046, 0x00000000, 0x91000080, 0x800000c2, 0x00155543, 0x001020f2, 0x00000000,
13805         0x00100046, 0x00000000, 0x00208ae6, 0x00000000, 0x00000000, 0x00107e46, 0x00000000, 0x0010600a,
13806         0x00000000, 0x0020800a, 0x00000000, 0x00000001, 0x0100003e,
13807     };
13808     static const D3D12_SHADER_BYTECODE ps_gather4_po_c = {gather4_po_c_code, sizeof(gather4_po_c_code)};
13809     static const float texture_data[] =
13810     {
13811         0.0f, 1.0f, 0.20f, 0.30f,
13812         0.4f, 0.5f, 0.60f, 0.70f,
13813         0.8f, 0.9f, 0.50f, 0.15f,
13814         0.2f, 0.3f, 0.45f, 0.55f,
13815     };
13816     static const struct vec4 expected_gather4_c[] =
13817     {
13818         {0.0f, 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 0.0f, 0.0f},
13819         {1.0f, 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 1.0f, 1.0f},
13820         {0.0f, 0.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 1.0f, 1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 0.0f, 0.0f},
13821         {0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f},
13822     };
13823     static const struct vec4 expected_gather4_po_c[] =
13824     {
13825         {1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 1.0f, 1.0f},
13826         {0.0f, 0.0f, 1.0f, 1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 0.0f, 0.0f},
13827         {0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f},
13828         {0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f},
13829     };
13830     static const struct vec4 white = {1.0f, 1.0f, 1.0f, 1.0f};
13831     static const D3D12_SUBRESOURCE_DATA resource_data = {&texture_data, sizeof(texture_data) / 4};
13832     static const D3D12_STATIC_SAMPLER_DESC sampler_desc =
13833     {
13834         .Filter = D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT,
13835         .AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
13836         .AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
13837         .AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
13838         .ComparisonFunc = D3D12_COMPARISON_FUNC_LESS,
13839         .MaxLOD = D3D12_FLOAT32_MAX,
13840         .ShaderRegister = 0,
13841         .RegisterSpace = 0,
13842         .ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
13843     };
13844 
13845     memset(&desc, 0, sizeof(desc));
13846     desc.rt_width = 4;
13847     desc.rt_height = 4;
13848     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
13849     desc.no_root_signature = true;
13850     if (!init_test_context(&context, &desc))
13851         return;
13852     command_list = context.list;
13853     queue = context.queue;
13854 
13855     context.root_signature = create_texture_root_signature_(__LINE__, context.device,
13856             D3D12_SHADER_VISIBILITY_PIXEL, 5, 0, &sampler_desc);
13857 
13858     heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
13859     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
13860     gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
13861 
13862     texture = create_default_texture(context.device, 4, 4, DXGI_FORMAT_R32_TYPELESS,
13863             0, D3D12_RESOURCE_STATE_COPY_DEST);
13864     upload_texture_data(texture, &resource_data, 1, queue, command_list);
13865     reset_command_list(command_list, context.allocator);
13866     transition_resource_state(command_list, texture,
13867             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
13868 
13869     memset(&srv_desc, 0, sizeof(srv_desc));
13870     srv_desc.Format = DXGI_FORMAT_R32_FLOAT;
13871     srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
13872     srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
13873     srv_desc.Texture2D.MipLevels = 1;
13874     ID3D12Device_CreateShaderResourceView(context.device, texture, &srv_desc, cpu_handle);
13875 
13876     constants.width = 4;
13877     constants.height = 4;
13878     constants.offset_x = 1;
13879     constants.offset_y = 1;
13880     constants.d_ref = 0.46f;
13881 
13882     /* ps_gather4_c */
13883     context.pipeline_state = create_pipeline_state(context.device,
13884             context.root_signature, desc.rt_format, NULL, &ps_gather4_c, NULL);
13885 
13886     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
13887 
13888     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
13889     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
13890     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
13891     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
13892     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
13893     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 5, &constants.width, 0);
13894     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
13895     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
13896     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
13897     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
13898 
13899     transition_resource_state(command_list, context.render_target,
13900             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
13901     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
13902     for (y = 0; y < rb.height; ++y)
13903     {
13904         for (x = 0; x < rb.width; ++x)
13905         {
13906             const struct vec4 *expected = &expected_gather4_c[y * rb.width + x];
13907             const struct vec4 *got = get_readback_vec4(&rb, x, y);
13908             ok(compare_vec4(got, expected, 0),
13909                     "Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
13910                     got->x, got->y, got->z, got->w, expected->x, expected->y, expected->z, expected->w);
13911         }
13912     }
13913     release_resource_readback(&rb);
13914 
13915     ID3D12PipelineState_Release(context.pipeline_state);
13916     reset_command_list(command_list, context.allocator);
13917     transition_resource_state(command_list, context.render_target,
13918             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
13919 
13920     /* ps_gather4_po_c */
13921     context.pipeline_state = create_pipeline_state(context.device,
13922             context.root_signature, desc.rt_format, NULL, &ps_gather4_po_c, NULL);
13923 
13924     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
13925 
13926     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
13927     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
13928     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
13929     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
13930     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
13931     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 5, &constants.width, 0);
13932     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
13933     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
13934     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
13935     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
13936 
13937     transition_resource_state(command_list, context.render_target,
13938             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
13939     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
13940     for (y = 0; y < rb.height; ++y)
13941     {
13942         for (x = 0; x < rb.width; ++x)
13943         {
13944             const struct vec4 *expected = &expected_gather4_po_c[y * rb.width + x];
13945             const struct vec4 *got = get_readback_vec4(&rb, x, y);
13946             ok(compare_vec4(got, expected, 0),
13947                     "Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
13948                     got->x, got->y, got->z, got->w, expected->x, expected->y, expected->z, expected->w);
13949         }
13950     }
13951     release_resource_readback(&rb);
13952 
13953     reset_command_list(command_list, context.allocator);
13954     transition_resource_state(command_list, context.render_target,
13955             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
13956 
13957     constants.offset_x = 0;
13958     constants.offset_y = 0;
13959 
13960     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, &white.x, 0, NULL);
13961 
13962     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
13963     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
13964     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
13965     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
13966     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
13967     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 5, &constants.width, 0);
13968     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
13969     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
13970     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
13971     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
13972 
13973     transition_resource_state(command_list, context.render_target,
13974             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
13975     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
13976     for (y = 0; y < rb.height; ++y)
13977     {
13978         for (x = 0; x < rb.width; ++x)
13979         {
13980             const struct vec4 *expected = &expected_gather4_c[y * rb.width + x];
13981             const struct vec4 *got = get_readback_vec4(&rb, x, y);
13982             ok(compare_vec4(got, expected, 0),
13983                     "Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
13984                     got->x, got->y, got->z, got->w, expected->x, expected->y, expected->z, expected->w);
13985         }
13986     }
13987     release_resource_readback(&rb);
13988 
13989     ID3D12Resource_Release(texture);
13990     ID3D12DescriptorHeap_Release(heap);
13991     destroy_test_context(&context);
13992 }
13993 
test_sample_c_lz(void)13994 static void test_sample_c_lz(void)
13995 {
13996     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
13997     ID3D12GraphicsCommandList *command_list;
13998     D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc;
13999     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
14000     struct depth_stencil_resource ds;
14001     struct test_context_desc desc;
14002     struct resource_readback rb;
14003     struct test_context context;
14004     ID3D12DescriptorHeap *heap;
14005     ID3D12CommandQueue *queue;
14006     struct vec4 ps_constant;
14007     ID3D12Device *device;
14008     unsigned int i;
14009     RECT rect;
14010 
14011     static const D3D12_STATIC_SAMPLER_DESC sampler_desc =
14012     {
14013         .Filter = D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR,
14014         .AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
14015         .AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
14016         .AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
14017         .ComparisonFunc = D3D12_COMPARISON_FUNC_GREATER,
14018         .MaxAnisotropy = 0,
14019         .BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE,
14020         .MaxLOD = 10.0f,
14021     };
14022     static const float clear_color[] = {0.5f, 0.5f, 0.5f, 0.5f};
14023     static const DWORD ps_array_code[] =
14024     {
14025 #if 0
14026         Texture2DArray t;
14027         SamplerComparisonState s;
14028 
14029         float ref;
14030         float layer;
14031 
14032         float4 main(float4 position : SV_Position) : SV_Target
14033         {
14034             return t.SampleCmpLevelZero(s, float3(position.x / 640.0f, position.y / 480.0f, layer), ref);
14035         }
14036 #endif
14037         0x43425844, 0xfe28b3c3, 0xdd7ef404, 0x8d5874a1, 0x984ff182, 0x00000001, 0x00000180, 0x00000003,
14038         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
14039         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
14040         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
14041         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000e4, 0x00000041,
14042         0x00000039, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300085a, 0x00106000,
14043         0x00000000, 0x04004058, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000,
14044         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0a000038, 0x00100032,
14045         0x00000000, 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000,
14046         0x06000036, 0x00100042, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x0c000047, 0x00100012,
14047         0x00000000, 0x00100246, 0x00000000, 0x00107006, 0x00000000, 0x00106000, 0x00000000, 0x0020800a,
14048         0x00000000, 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00100006, 0x00000000, 0x0100003e,
14049     };
14050     static const D3D12_SHADER_BYTECODE ps_array = {ps_array_code, sizeof(ps_array_code)};
14051     static const DWORD ps_cube_code[] =
14052     {
14053 #if 0
14054         TextureCube t;
14055         SamplerComparisonState s;
14056 
14057         float ref;
14058         float face;
14059 
14060         float4 main(float4 position : SV_Position) : SV_Target
14061         {
14062             float2 p;
14063             p.x = position.x / 640.0f;
14064             p.y = position.y / 480.0f;
14065 
14066             float3 coord;
14067             switch ((uint)face)
14068             {
14069                 case 0:
14070                     coord = float3(1.0f, p.x, p.y);
14071                     break;
14072                 case 1:
14073                     coord = float3(-1.0f, p.x, p.y);
14074                     break;
14075                 case 2:
14076                     coord = float3(p.x, 1.0f, p.y);
14077                     break;
14078                 case 3:
14079                     coord = float3(p.x, -1.0f, p.y);
14080                     break;
14081                 case 4:
14082                     coord = float3(p.x, p.y, 1.0f);
14083                     break;
14084                 case 5:
14085                 default:
14086                     coord = float3(p.x, p.y, -1.0f);
14087                     break;
14088             }
14089 
14090             return t.SampleCmpLevelZero(s, coord, ref);
14091         }
14092 #endif
14093         0x43425844, 0xde5655e5, 0x1b116fa1, 0xfce9e757, 0x41c28aac, 0x00000001, 0x00000328, 0x00000003,
14094         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
14095         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
14096         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
14097         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x0000028c, 0x00000041,
14098         0x000000a3, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300085a, 0x00106000,
14099         0x00000000, 0x04003058, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000,
14100         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0600001c, 0x00100012,
14101         0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x0300004c, 0x0010000a, 0x00000000, 0x03000006,
14102         0x00004001, 0x00000000, 0x05000036, 0x00100012, 0x00000000, 0x00004001, 0x3f800000, 0x0a000038,
14103         0x00100062, 0x00000000, 0x00101106, 0x00000000, 0x00004002, 0x00000000, 0x3acccccd, 0x3b088889,
14104         0x00000000, 0x01000002, 0x03000006, 0x00004001, 0x00000001, 0x05000036, 0x00100012, 0x00000000,
14105         0x00004001, 0xbf800000, 0x0a000038, 0x00100062, 0x00000000, 0x00101106, 0x00000000, 0x00004002,
14106         0x00000000, 0x3acccccd, 0x3b088889, 0x00000000, 0x01000002, 0x03000006, 0x00004001, 0x00000002,
14107         0x0a000038, 0x00100052, 0x00000000, 0x00101106, 0x00000000, 0x00004002, 0x3acccccd, 0x00000000,
14108         0x3b088889, 0x00000000, 0x05000036, 0x00100022, 0x00000000, 0x00004001, 0x3f800000, 0x01000002,
14109         0x03000006, 0x00004001, 0x00000003, 0x0a000038, 0x00100052, 0x00000000, 0x00101106, 0x00000000,
14110         0x00004002, 0x3acccccd, 0x00000000, 0x3b088889, 0x00000000, 0x05000036, 0x00100022, 0x00000000,
14111         0x00004001, 0xbf800000, 0x01000002, 0x03000006, 0x00004001, 0x00000004, 0x0a000038, 0x00100032,
14112         0x00000000, 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000,
14113         0x05000036, 0x00100042, 0x00000000, 0x00004001, 0x3f800000, 0x01000002, 0x0100000a, 0x0a000038,
14114         0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000,
14115         0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x00004001, 0xbf800000, 0x01000002, 0x01000017,
14116         0x0c000047, 0x00100012, 0x00000000, 0x00100246, 0x00000000, 0x00107006, 0x00000000, 0x00106000,
14117         0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00100006,
14118         0x00000000, 0x0100003e,
14119     };
14120     static const D3D12_SHADER_BYTECODE ps_cube = {ps_cube_code, sizeof(ps_cube_code)};
14121     static const float depth_values[] = {1.0f, 0.0f, 0.5f, 0.6f, 0.4f, 0.1f};
14122     static const struct
14123     {
14124         unsigned int layer;
14125         float d_ref;
14126         float expected;
14127     }
14128     tests[] =
14129     {
14130         {0, 0.5f, 0.0f},
14131         {1, 0.5f, 1.0f},
14132         {2, 0.5f, 0.0f},
14133         {3, 0.5f, 0.0f},
14134         {4, 0.5f, 1.0f},
14135         {5, 0.5f, 1.0f},
14136 
14137         {0, 0.0f, 0.0f},
14138         {1, 0.0f, 0.0f},
14139         {2, 0.0f, 0.0f},
14140         {3, 0.0f, 0.0f},
14141         {4, 0.0f, 0.0f},
14142         {5, 0.0f, 0.0f},
14143 
14144         {0, 1.0f, 0.0f},
14145         {1, 1.0f, 1.0f},
14146         {2, 1.0f, 1.0f},
14147         {3, 1.0f, 1.0f},
14148         {4, 1.0f, 1.0f},
14149         {5, 1.0f, 1.0f},
14150     };
14151 
14152     memset(&desc, 0, sizeof(desc));
14153     desc.rt_width = 640;
14154     desc.rt_height = 480;
14155     desc.rt_format = DXGI_FORMAT_R32_FLOAT;
14156     desc.no_root_signature = true;
14157     if (!init_test_context(&context, &desc))
14158         return;
14159     device = context.device;
14160     command_list = context.list;
14161     queue = context.queue;
14162 
14163     context.root_signature = create_texture_root_signature_(__LINE__, device,
14164             D3D12_SHADER_VISIBILITY_PIXEL, 4, 0, &sampler_desc);
14165 
14166     heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 6);
14167     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
14168 
14169     /* 2D array texture */
14170     context.pipeline_state = create_pipeline_state(context.device,
14171             context.root_signature, context.render_target_desc.Format, NULL, &ps_array, NULL);
14172 
14173     init_depth_stencil(&ds, device, 32, 32, ARRAY_SIZE(depth_values), 2,
14174             DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_D32_FLOAT, NULL);
14175 
14176     for (i = 0; i < ARRAY_SIZE(depth_values); ++i)
14177     {
14178         memset(&dsv_desc, 0, sizeof(dsv_desc));
14179         dsv_desc.Format = DXGI_FORMAT_D32_FLOAT;
14180         dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DARRAY;
14181         dsv_desc.Texture2DArray.FirstArraySlice = i;
14182         dsv_desc.Texture2DArray.ArraySize = 1;
14183         ID3D12Device_CreateDepthStencilView(device, ds.texture, &dsv_desc, ds.dsv_handle);
14184         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
14185                 D3D12_CLEAR_FLAG_DEPTH, depth_values[i], 0, 0, NULL);
14186 
14187         dsv_desc.Texture2DArray.MipSlice = 1;
14188         ID3D12Device_CreateDepthStencilView(device, ds.texture, &dsv_desc, ds.dsv_handle);
14189         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
14190                 D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, NULL);
14191     }
14192 
14193     memset(&srv_desc, 0, sizeof(srv_desc));
14194     srv_desc.Format = DXGI_FORMAT_R32_FLOAT;
14195     srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
14196     srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
14197     srv_desc.Texture2DArray.MostDetailedMip = 0;
14198     srv_desc.Texture2DArray.MipLevels = 2;
14199     srv_desc.Texture2DArray.FirstArraySlice = 0;
14200     srv_desc.Texture2DArray.ArraySize = ARRAY_SIZE(depth_values);
14201     ID3D12Device_CreateShaderResourceView(context.device, ds.texture, &srv_desc, cpu_handle);
14202 
14203     transition_resource_state(command_list, ds.texture,
14204             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
14205 
14206     memset(&ps_constant, 0, sizeof(ps_constant));
14207     for (i = 0; i < ARRAY_SIZE(tests); ++i)
14208     {
14209         vkd3d_test_set_context("test %u", i);
14210 
14211         ps_constant.x = tests[i].d_ref;
14212         ps_constant.y = tests[i].layer;
14213 
14214         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, clear_color, 0, NULL);
14215         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
14216         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
14217         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
14218         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
14219         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
14220                     get_gpu_descriptor_handle(&context, heap, 0));
14221         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &ps_constant.x, 0);
14222         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
14223         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
14224         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
14225         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
14226 
14227         transition_resource_state(command_list, context.render_target,
14228                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
14229 
14230         check_sub_resource_float(context.render_target, 0, queue, command_list, tests[i].expected, 2);
14231 
14232         reset_command_list(command_list, context.allocator);
14233         transition_resource_state(command_list, context.render_target,
14234                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
14235     }
14236     vkd3d_test_set_context(NULL);
14237 
14238     ID3D12PipelineState_Release(context.pipeline_state);
14239 
14240     /* cube texture */
14241     context.pipeline_state = create_pipeline_state(context.device,
14242             context.root_signature, context.render_target_desc.Format, NULL, &ps_cube, NULL);
14243 
14244     memset(&srv_desc, 0, sizeof(srv_desc));
14245     srv_desc.Format = DXGI_FORMAT_R32_FLOAT;
14246     srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
14247     srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
14248     srv_desc.TextureCube.MostDetailedMip = 0;
14249     srv_desc.TextureCube.MipLevels = 2;
14250     ID3D12Device_CreateShaderResourceView(context.device, ds.texture, &srv_desc, cpu_handle);
14251 
14252     for (i = 0; i < ARRAY_SIZE(tests); ++i)
14253     {
14254         vkd3d_test_set_context("test %u", i);
14255 
14256         ps_constant.x = tests[i].d_ref;
14257         ps_constant.y = tests[i].layer;
14258 
14259         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, clear_color, 0, NULL);
14260         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
14261         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
14262         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
14263         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
14264         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
14265                     get_gpu_descriptor_handle(&context, heap, 0));
14266         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &ps_constant.x, 0);
14267         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
14268         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
14269         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
14270         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
14271 
14272         transition_resource_state(command_list, context.render_target,
14273                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
14274 
14275         get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
14276         /* Avoid testing values affected by seamless cube map filtering. */
14277         set_rect(&rect, 100, 100, 540, 380);
14278         check_readback_data_float(&rb, &rect, tests[i].expected, 2);
14279         release_resource_readback(&rb);
14280 
14281         reset_command_list(command_list, context.allocator);
14282         transition_resource_state(command_list, context.render_target,
14283                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
14284     }
14285     vkd3d_test_set_context(NULL);
14286 
14287     destroy_depth_stencil(&ds);
14288     ID3D12DescriptorHeap_Release(heap);
14289     destroy_test_context(&context);
14290 }
14291 
test_cube_maps(void)14292 static void test_cube_maps(void)
14293 {
14294     unsigned int i, j, sub_resource_idx, sub_resource_count;
14295     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
14296     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
14297     ID3D12GraphicsCommandList *command_list;
14298     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
14299     D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
14300     D3D12_SUBRESOURCE_DATA *texture_data;
14301     const D3D12_SHADER_BYTECODE *ps;
14302     struct test_context_desc desc;
14303     struct test_context context;
14304     ID3D12DescriptorHeap *heap;
14305     ID3D12CommandQueue *queue;
14306     ID3D12PipelineState *pso;
14307     ID3D12Resource *texture;
14308     float *data;
14309     HRESULT hr;
14310 
14311     struct
14312     {
14313         unsigned int face;
14314         unsigned int level;
14315         unsigned int cube;
14316     } constants;
14317 
14318     const unsigned int texture_size = 64;
14319     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
14320     static const DWORD ps_cube_code[] =
14321     {
14322 #if 0
14323         TextureCube t;
14324         SamplerState s;
14325 
14326         uint face;
14327         uint level;
14328 
14329         float4 main(float4 position : SV_POSITION) : SV_Target
14330         {
14331             float2 p;
14332             p.x = position.x / 640.0f;
14333             p.y = position.y / 480.0f;
14334 
14335             float3 coord;
14336             switch (face)
14337             {
14338                 case 0:
14339                     coord = float3(1.0f, p.x, p.y);
14340                     break;
14341                 case 1:
14342                     coord = float3(-1.0f, p.x, p.y);
14343                     break;
14344                 case 2:
14345                     coord = float3(p.x, 1.0f, p.y);
14346                     break;
14347                 case 3:
14348                     coord = float3(p.x, -1.0f, p.y);
14349                     break;
14350                 case 4:
14351                     coord = float3(p.x, p.y, 1.0f);
14352                     break;
14353                 case 5:
14354                 default:
14355                     coord = float3(p.x, p.y, -1.0f);
14356                     break;
14357             }
14358             return t.SampleLevel(s, coord, level);
14359         }
14360 #endif
14361         0x43425844, 0x039aee18, 0xfd630453, 0xb884cf0f, 0x10100744, 0x00000001, 0x00000310, 0x00000003,
14362         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
14363         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
14364         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
14365         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000274, 0x00000040,
14366         0x0000009d, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000, 0x00000000,
14367         0x04003058, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001,
14368         0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0400004c, 0x0020800a, 0x00000000,
14369         0x00000000, 0x03000006, 0x00004001, 0x00000000, 0x05000036, 0x00100012, 0x00000000, 0x00004001,
14370         0x3f800000, 0x0a000038, 0x00100062, 0x00000000, 0x00101106, 0x00000000, 0x00004002, 0x00000000,
14371         0x3acccccd, 0x3b088889, 0x00000000, 0x01000002, 0x03000006, 0x00004001, 0x00000001, 0x05000036,
14372         0x00100012, 0x00000000, 0x00004001, 0xbf800000, 0x0a000038, 0x00100062, 0x00000000, 0x00101106,
14373         0x00000000, 0x00004002, 0x00000000, 0x3acccccd, 0x3b088889, 0x00000000, 0x01000002, 0x03000006,
14374         0x00004001, 0x00000002, 0x0a000038, 0x00100052, 0x00000000, 0x00101106, 0x00000000, 0x00004002,
14375         0x3acccccd, 0x00000000, 0x3b088889, 0x00000000, 0x05000036, 0x00100022, 0x00000000, 0x00004001,
14376         0x3f800000, 0x01000002, 0x03000006, 0x00004001, 0x00000003, 0x0a000038, 0x00100052, 0x00000000,
14377         0x00101106, 0x00000000, 0x00004002, 0x3acccccd, 0x00000000, 0x3b088889, 0x00000000, 0x05000036,
14378         0x00100022, 0x00000000, 0x00004001, 0xbf800000, 0x01000002, 0x03000006, 0x00004001, 0x00000004,
14379         0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889,
14380         0x00000000, 0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x00004001, 0x3f800000, 0x01000002,
14381         0x0100000a, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002, 0x3acccccd,
14382         0x3b088889, 0x00000000, 0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x00004001, 0xbf800000,
14383         0x01000002, 0x01000017, 0x06000056, 0x00100082, 0x00000000, 0x0020801a, 0x00000000, 0x00000000,
14384         0x0b000048, 0x001020f2, 0x00000000, 0x00100246, 0x00000000, 0x00107e46, 0x00000000, 0x00106000,
14385         0x00000000, 0x0010003a, 0x00000000, 0x0100003e,
14386     };
14387     static const D3D12_SHADER_BYTECODE ps_cube = {ps_cube_code, sizeof(ps_cube_code)};
14388     static const DWORD ps_cube_array_code[] =
14389     {
14390 #if 0
14391         TextureCubeArray t;
14392         SamplerState s;
14393 
14394         uint face;
14395         uint level;
14396         uint cube;
14397 
14398         float4 main(float4 position : SV_POSITION) : SV_Target
14399         {
14400             float2 p;
14401             p.x = position.x / 640.0f;
14402             p.y = position.y / 480.0f;
14403 
14404             float3 coord;
14405             switch (face)
14406             {
14407                 case 0:
14408                     coord = float3(1.0f, p.x, p.y);
14409                     break;
14410                 case 1:
14411                     coord = float3(-1.0f, p.x, p.y);
14412                     break;
14413                 case 2:
14414                     coord = float3(p.x, 1.0f, p.y);
14415                     break;
14416                 case 3:
14417                     coord = float3(p.x, -1.0f, p.y);
14418                     break;
14419                 case 4:
14420                     coord = float3(p.x, p.y, 1.0f);
14421                     break;
14422                 case 5:
14423                 default:
14424                     coord = float3(p.x, p.y, -1.0f);
14425                     break;
14426             }
14427             return t.SampleLevel(s, float4(coord, cube), level);
14428         }
14429 #endif
14430         0x43425844, 0xb8d5b94a, 0xdb4be034, 0x183aed19, 0xad4af415, 0x00000001, 0x00000328, 0x00000003,
14431         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
14432         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
14433         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
14434         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x0000028c, 0x00000041,
14435         0x000000a3, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000,
14436         0x00000000, 0x04005058, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000,
14437         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x0400004c, 0x0020800a,
14438         0x00000000, 0x00000000, 0x03000006, 0x00004001, 0x00000000, 0x05000036, 0x00100012, 0x00000000,
14439         0x00004001, 0x3f800000, 0x0a000038, 0x00100062, 0x00000000, 0x00101106, 0x00000000, 0x00004002,
14440         0x00000000, 0x3acccccd, 0x3b088889, 0x00000000, 0x01000002, 0x03000006, 0x00004001, 0x00000001,
14441         0x05000036, 0x00100012, 0x00000000, 0x00004001, 0xbf800000, 0x0a000038, 0x00100062, 0x00000000,
14442         0x00101106, 0x00000000, 0x00004002, 0x00000000, 0x3acccccd, 0x3b088889, 0x00000000, 0x01000002,
14443         0x03000006, 0x00004001, 0x00000002, 0x0a000038, 0x00100052, 0x00000000, 0x00101106, 0x00000000,
14444         0x00004002, 0x3acccccd, 0x00000000, 0x3b088889, 0x00000000, 0x05000036, 0x00100022, 0x00000000,
14445         0x00004001, 0x3f800000, 0x01000002, 0x03000006, 0x00004001, 0x00000003, 0x0a000038, 0x00100052,
14446         0x00000000, 0x00101106, 0x00000000, 0x00004002, 0x3acccccd, 0x00000000, 0x3b088889, 0x00000000,
14447         0x05000036, 0x00100022, 0x00000000, 0x00004001, 0xbf800000, 0x01000002, 0x03000006, 0x00004001,
14448         0x00000004, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002, 0x3acccccd,
14449         0x3b088889, 0x00000000, 0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x00004001, 0x3f800000,
14450         0x01000002, 0x0100000a, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002,
14451         0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x00004001,
14452         0xbf800000, 0x01000002, 0x01000017, 0x06000056, 0x00100032, 0x00000001, 0x00208a66, 0x00000000,
14453         0x00000000, 0x05000036, 0x00100082, 0x00000000, 0x0010000a, 0x00000001, 0x0b000048, 0x001020f2,
14454         0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0010001a,
14455         0x00000001, 0x0100003e,
14456     };
14457     static const D3D12_SHADER_BYTECODE ps_cube_array = {ps_cube_array_code, sizeof(ps_cube_array_code)};
14458     static const struct ps_test
14459     {
14460         const D3D12_SHADER_BYTECODE *ps;
14461         unsigned int miplevel_count;
14462         unsigned int array_size;
14463         unsigned int cube_count;
14464     }
14465     ps_tests[] =
14466     {
14467         {&ps_cube, 1, 6, 1},
14468         {&ps_cube, 2, 6, 1},
14469         {&ps_cube, 3, 6, 1},
14470         {&ps_cube, 3, 6, ~0u},
14471 
14472         {&ps_cube_array, 1, 12, 2},
14473         {&ps_cube_array, 1, 12, ~0u},
14474         {&ps_cube_array, 2, 12, 2},
14475         {&ps_cube_array, 3, 12, 2},
14476         {&ps_cube_array, 3, 12, ~0u},
14477     };
14478 
14479     memset(&desc, 0, sizeof(desc));
14480     desc.rt_width = 640;
14481     desc.rt_height = 480;
14482     desc.rt_format = DXGI_FORMAT_R32_FLOAT;
14483     desc.no_root_signature = true;
14484     if (!init_test_context(&context, &desc))
14485         return;
14486     command_list = context.list;
14487     queue = context.queue;
14488 
14489     context.root_signature = create_texture_root_signature(context.device,
14490             D3D12_SHADER_VISIBILITY_PIXEL, 3, 0);
14491 
14492     init_pipeline_state_desc(&pso_desc, context.root_signature,
14493             context.render_target_desc.Format, NULL, NULL, NULL);
14494 
14495     heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
14496     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
14497     gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
14498 
14499     ps = NULL;
14500     pso = NULL;
14501     for (i = 0; i < ARRAY_SIZE(ps_tests); ++i)
14502     {
14503         const struct ps_test *test = &ps_tests[i];
14504 
14505         if (ps != test->ps)
14506         {
14507             if (pso)
14508                 ID3D12PipelineState_Release(pso);
14509 
14510             ps = test->ps;
14511             pso_desc.PS = *test->ps;
14512             hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
14513                     &IID_ID3D12PipelineState, (void **)&pso);
14514             ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
14515         }
14516 
14517         texture = create_default_texture2d(context.device, texture_size, texture_size,
14518                 test->array_size, test->miplevel_count, DXGI_FORMAT_R32_FLOAT,
14519                 D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
14520         srv_desc.Format = DXGI_FORMAT_R32_FLOAT;
14521         srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
14522         if (ps == &ps_cube)
14523         {
14524             srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
14525             srv_desc.TextureCube.MostDetailedMip = 0;
14526             srv_desc.TextureCube.MipLevels = test->miplevel_count;
14527             srv_desc.TextureCube.ResourceMinLODClamp = 0.0f;
14528         }
14529         else
14530         {
14531             srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
14532             srv_desc.TextureCubeArray.MostDetailedMip = 0;
14533             srv_desc.TextureCubeArray.MipLevels = test->miplevel_count;
14534             srv_desc.TextureCubeArray.First2DArrayFace = 0;
14535             srv_desc.TextureCubeArray.NumCubes = test->cube_count;
14536             srv_desc.TextureCubeArray.ResourceMinLODClamp = 0.0f;
14537         }
14538         ID3D12Device_CreateShaderResourceView(context.device, texture, &srv_desc, cpu_handle);
14539 
14540         sub_resource_count = test->array_size * test->miplevel_count;
14541         texture_data = calloc(sub_resource_count, sizeof(*texture_data));
14542         ok(texture_data, "Failed to allocate memory.\n");
14543         for (sub_resource_idx = 0; sub_resource_idx < sub_resource_count; ++sub_resource_idx)
14544         {
14545             data = calloc(texture_size * texture_size, sizeof(*data));
14546             ok(data, "Failed to allocate memory.\n");
14547             for (j = 0; j < texture_size * texture_size; ++j)
14548                 data[j] = sub_resource_idx;
14549 
14550             texture_data[sub_resource_idx].pData = data;
14551             texture_data[sub_resource_idx].RowPitch = texture_size * sizeof(*data);
14552             texture_data[sub_resource_idx].SlicePitch = 0;
14553         }
14554         upload_texture_data(texture, texture_data, sub_resource_count, queue, command_list);
14555         for (sub_resource_idx = 0; sub_resource_idx < sub_resource_count; ++sub_resource_idx)
14556             free((void *)texture_data[sub_resource_idx].pData);
14557         free(texture_data);
14558 
14559         reset_command_list(command_list, context.allocator);
14560         transition_resource_state(command_list, texture,
14561                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
14562 
14563         for (sub_resource_idx = 0; sub_resource_idx < sub_resource_count; ++sub_resource_idx)
14564         {
14565             constants.face = (sub_resource_idx / test->miplevel_count) % 6;
14566             constants.level = sub_resource_idx % test->miplevel_count;
14567             constants.cube = (sub_resource_idx / test->miplevel_count) / 6;
14568 
14569             ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
14570             ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
14571             ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
14572             ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
14573             ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
14574             ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
14575             ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 3, &constants.face, 0);
14576             ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
14577             ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
14578             ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
14579             ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
14580 
14581             transition_resource_state(command_list, context.render_target,
14582                     D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
14583 
14584             check_sub_resource_float(context.render_target, 0, queue, command_list, sub_resource_idx, 0);
14585 
14586             reset_command_list(command_list, context.allocator);
14587             transition_resource_state(command_list, context.render_target,
14588                     D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
14589         }
14590 
14591         ID3D12Resource_Release(texture);
14592     }
14593     ID3D12PipelineState_Release(pso);
14594 
14595     ID3D12DescriptorHeap_Release(heap);
14596     destroy_test_context(&context);
14597 }
14598 
test_multisample_array_texture(void)14599 static void test_multisample_array_texture(void)
14600 {
14601     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
14602     D3D12_ROOT_PARAMETER root_parameters[3];
14603     D3D12_DESCRIPTOR_RANGE descriptor_range;
14604     ID3D12GraphicsCommandList *command_list;
14605     D3D12_RENDER_TARGET_VIEW_DESC rtv_desc;
14606     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
14607     D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
14608     D3D12_HEAP_PROPERTIES heap_properties;
14609     D3D12_RESOURCE_DESC resource_desc;
14610     struct test_context_desc desc;
14611     struct resource_readback rb;
14612     struct test_context context;
14613     ID3D12DescriptorHeap *heap;
14614     ID3D12Resource *uav_buffer;
14615     ID3D12CommandQueue *queue;
14616     ID3D12Resource *texture;
14617     ID3D12Device *device;
14618     unsigned int i;
14619     HRESULT hr;
14620 
14621     static const DWORD ps_code[] =
14622     {
14623 #if 0
14624         Texture2DMSArray<float4> t;
14625 
14626         RWByteAddressBuffer u;
14627 
14628         uint layer;
14629         uint sample_index;
14630 
14631         uint offset;
14632 
14633         float4 main() : SV_Target
14634         {
14635             uint width, height, elements, samples;
14636             t.GetDimensions(width, height, elements, samples);
14637             u.Store4(offset, uint4(width, height, elements, samples));
14638             return t.Load(int3(0, 0, layer), sample_index);
14639         }
14640 #endif
14641         0x43425844, 0xb1457478, 0xd475e3dd, 0xda1eb41d, 0x66075d2b, 0x00000001, 0x0000017c, 0x00000003,
14642         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
14643         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
14644         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000104, 0x00000050, 0x00000041,
14645         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04004858, 0x00107000, 0x00000000,
14646         0x00005555, 0x0300009d, 0x0011e000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
14647         0x00000001, 0x8900103d, 0x80000242, 0x00155543, 0x00100072, 0x00000000, 0x00004001, 0x00000000,
14648         0x00107e46, 0x00000000, 0x0500086f, 0x00100082, 0x00000000, 0x0010700a, 0x00000000, 0x080000a6,
14649         0x0011e0f2, 0x00000001, 0x0020802a, 0x00000000, 0x00000000, 0x00100e46, 0x00000000, 0x05000036,
14650         0x00100012, 0x00000000, 0x00004001, 0x00000000, 0x06000036, 0x00100042, 0x00000000, 0x0020800a,
14651         0x00000000, 0x00000000, 0x8c00002e, 0x80000242, 0x00155543, 0x001020f2, 0x00000000, 0x00100206,
14652         0x00000000, 0x00107e46, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x0100003e,
14653     };
14654     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
14655     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
14656     static const struct vec4 colors[] =
14657     {
14658         {1.0f, 0.0f, 0.0f, 1.0f},
14659         {0.0f, 1.0f, 0.0f, 1.0f},
14660         {0.0f, 0.0f, 1.0f, 1.0f},
14661 
14662         {0.0f, 1.0f, 1.0f, 1.0f},
14663         {1.0f, 0.0f, 1.0f, 1.0f},
14664         {1.0f, 1.0f, 0.0f, 1.0f},
14665 
14666         {0.5f, 0.5f, 0.5f, 1.0f},
14667         {0.5f, 0.5f, 0.5f, 0.5f},
14668     };
14669     static const struct
14670     {
14671         struct
14672         {
14673             unsigned int layer;
14674             unsigned int sample_index;
14675             unsigned int offset;
14676         } constants;
14677         unsigned int expected_color;
14678     }
14679     tests[] =
14680     {
14681         {{0, 0,  0}, 0xff0000ff},
14682         {{0, 1,  0}, 0xff0000ff},
14683         {{0, 2,  0}, 0xff0000ff},
14684         {{0, 3,  0}, 0xff0000ff},
14685 
14686         {{1, 0, 16}, 0xff00ff00},
14687         {{2, 1, 32}, 0xffff0000},
14688         {{3, 2, 32}, 0xffffff00},
14689         {{4, 3, 32}, 0xffff00ff},
14690         {{5, 0, 32}, 0xff00ffff},
14691         {{6, 0, 32}, 0xff7f7f7f},
14692         {{7, 0, 32}, 0x7f7f7f7f},
14693     };
14694 
14695     memset(&desc, 0, sizeof(desc));
14696     desc.rt_descriptor_count = 2;
14697     desc.no_root_signature = true;
14698     if (!init_test_context(&context, &desc))
14699         return;
14700     device = context.device;
14701     command_list = context.list;
14702     queue = context.queue;
14703 
14704     descriptor_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
14705     descriptor_range.NumDescriptors = 1;
14706     descriptor_range.BaseShaderRegister = 0;
14707     descriptor_range.RegisterSpace = 0;
14708     descriptor_range.OffsetInDescriptorsFromTableStart = 0;
14709     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
14710     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
14711     root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_range;
14712     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
14713     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
14714     root_parameters[1].Constants.ShaderRegister = 0;
14715     root_parameters[1].Constants.RegisterSpace = 0;
14716     root_parameters[1].Constants.Num32BitValues = 3;
14717     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
14718     root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
14719     root_parameters[2].Descriptor.ShaderRegister = 1;
14720     root_parameters[2].Descriptor.RegisterSpace = 0;
14721     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
14722 
14723     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
14724     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
14725     root_signature_desc.pParameters = root_parameters;
14726     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
14727     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
14728     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
14729 
14730     context.pipeline_state = create_pipeline_state(context.device,
14731             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
14732 
14733     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
14734 
14735     memset(&heap_properties, 0, sizeof(heap_properties));
14736     heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
14737 
14738     memset(&resource_desc, 0, sizeof(resource_desc));
14739     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
14740     resource_desc.Width = 32;
14741     resource_desc.Height = 32;
14742     resource_desc.DepthOrArraySize = ARRAY_SIZE(colors);
14743     resource_desc.MipLevels = 1;
14744     resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
14745     resource_desc.SampleDesc.Count = 4;
14746     resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
14747     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
14748             &resource_desc, D3D12_RESOURCE_STATE_RENDER_TARGET, NULL, &IID_ID3D12Resource, (void **)&texture);
14749     ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
14750 
14751     cpu_handle = get_cpu_rtv_handle(&context, context.rtv_heap, 1);
14752 
14753     for (i = 0; i < ARRAY_SIZE(colors); ++i)
14754     {
14755         memset(&rtv_desc, 0, sizeof(rtv_desc));
14756         rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY;
14757         rtv_desc.Format = resource_desc.Format;
14758         rtv_desc.Texture2DMSArray.FirstArraySlice = i;
14759         rtv_desc.Texture2DMSArray.ArraySize = 1;
14760         ID3D12Device_CreateRenderTargetView(device, texture, &rtv_desc, cpu_handle);
14761 
14762         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, cpu_handle, &colors[i].x, 0, NULL);
14763     }
14764 
14765     transition_resource_state(command_list, texture,
14766             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
14767 
14768     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
14769     gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
14770 
14771     ID3D12Device_CreateShaderResourceView(device, texture, NULL, cpu_handle);
14772 
14773     uav_buffer = create_default_buffer(device, 4096,
14774             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
14775 
14776     for (i = 0; i < ARRAY_SIZE(tests); ++i)
14777     {
14778         vkd3d_test_set_context("Test %u", i);
14779 
14780         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
14781         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
14782         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
14783         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
14784         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
14785         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
14786         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 3, &tests[i].constants.layer, 0);
14787         ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView(command_list,
14788                 2, ID3D12Resource_GetGPUVirtualAddress(uav_buffer));
14789         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
14790         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
14791         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
14792         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
14793 
14794         transition_resource_state(command_list, context.render_target,
14795                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
14796         check_sub_resource_uint(context.render_target, 0, queue, command_list, tests[i].expected_color, 1);
14797 
14798         reset_command_list(command_list, context.allocator);
14799         transition_resource_state(command_list, context.render_target,
14800                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
14801     }
14802     vkd3d_test_set_context(NULL);
14803 
14804     transition_resource_state(command_list, uav_buffer,
14805             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
14806 
14807     get_buffer_readback_with_command_list(uav_buffer, DXGI_FORMAT_R32G32B32A32_UINT, &rb, queue, command_list);
14808     for (i = 0; i < 2; ++i)
14809     {
14810         const struct uvec4 *v = get_readback_uvec4(&rb, i, 0);
14811         ok(v->x == resource_desc.Width, "Got unexpected width %u.\n", v->x);
14812         ok(v->y == resource_desc.Height, "Got unexpected height %u.\n", v->y);
14813         ok(v->z == resource_desc.DepthOrArraySize, "Got unexpected array size %u.\n", v->z);
14814         ok(v->w == resource_desc.SampleDesc.Count, "Got unexpected sample count %u.\n", v->w);
14815     }
14816     release_resource_readback(&rb);
14817 
14818     ID3D12Resource_Release(texture);
14819     ID3D12Resource_Release(uav_buffer);
14820     ID3D12DescriptorHeap_Release(heap);
14821     destroy_test_context(&context);
14822 }
14823 
test_resinfo(void)14824 static void test_resinfo(void)
14825 {
14826     D3D12_SHADER_RESOURCE_VIEW_DESC *current_srv_desc, srv_desc;
14827     const D3D12_SHADER_BYTECODE *current_ps;
14828     ID3D12GraphicsCommandList *command_list;
14829     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
14830     D3D12_HEAP_PROPERTIES heap_properties;
14831     D3D12_RESOURCE_DESC resource_desc;
14832     struct test_context_desc desc;
14833     struct test_context context;
14834     ID3D12DescriptorHeap *heap;
14835     ID3D12CommandQueue *queue;
14836     ID3D12Resource *texture;
14837     struct uvec4 constant;
14838     ID3D12Device *device;
14839     unsigned int i, type;
14840     HRESULT hr;
14841 
14842     static const DWORD ps_2d_code[] =
14843     {
14844 #if 0
14845         Texture2D t;
14846 
14847         uint type;
14848         uint level;
14849 
14850         float4 main() : SV_TARGET
14851         {
14852             if (!type)
14853             {
14854                 float width, height, miplevels;
14855                 t.GetDimensions(level, width, height, miplevels);
14856                 return float4(width, height, miplevels, 0);
14857             }
14858             else
14859             {
14860                 uint width, height, miplevels;
14861                 t.GetDimensions(level, width, height, miplevels);
14862                 return float4(width, height, miplevels, 0);
14863             }
14864         }
14865 #endif
14866         0x43425844, 0x9c2db58d, 0x7218d757, 0x23255414, 0xaa86938e, 0x00000001, 0x00000168, 0x00000003,
14867         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
14868         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
14869         0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x000000f0, 0x00000040, 0x0000003c,
14870         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555,
14871         0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0400001f, 0x0020800a, 0x00000000,
14872         0x00000000, 0x0800003d, 0x001000f2, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x00107e46,
14873         0x00000000, 0x05000036, 0x00102072, 0x00000000, 0x00100346, 0x00000000, 0x05000036, 0x00102082,
14874         0x00000000, 0x00004001, 0x00000000, 0x0100003e, 0x01000012, 0x0800103d, 0x001000f2, 0x00000000,
14875         0x0020801a, 0x00000000, 0x00000000, 0x00107e46, 0x00000000, 0x05000056, 0x00102072, 0x00000000,
14876         0x00100346, 0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x00004001, 0x00000000, 0x0100003e,
14877         0x01000015, 0x0100003e,
14878     };
14879     static const D3D12_SHADER_BYTECODE ps_2d = {ps_2d_code, sizeof(ps_2d_code)};
14880     static const DWORD ps_2d_array_code[] =
14881     {
14882 #if 0
14883         Texture2DArray t;
14884 
14885         uint type;
14886         uint level;
14887 
14888         float4 main() : SV_TARGET
14889         {
14890             if (!type)
14891             {
14892                 float width, height, elements, miplevels;
14893                 t.GetDimensions(level, width, height, elements, miplevels);
14894                 return float4(width, height, elements, miplevels);
14895             }
14896             else
14897             {
14898                 uint width, height, elements, miplevels;
14899                 t.GetDimensions(level, width, height, elements, miplevels);
14900                 return float4(width, height, elements, miplevels);
14901             }
14902         }
14903 #endif
14904         0x43425844, 0x92cd8789, 0x38e359ac, 0xd65ab502, 0xa018a5ae, 0x00000001, 0x0000012c, 0x00000003,
14905         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
14906         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
14907         0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x000000b4, 0x00000040, 0x0000002d,
14908         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04004058, 0x00107000, 0x00000000, 0x00005555,
14909         0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0400001f, 0x0020800a, 0x00000000,
14910         0x00000000, 0x0800003d, 0x001020f2, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x00107e46,
14911         0x00000000, 0x0100003e, 0x01000012, 0x0800103d, 0x001000f2, 0x00000000, 0x0020801a, 0x00000000,
14912         0x00000000, 0x00107e46, 0x00000000, 0x05000056, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
14913         0x0100003e, 0x01000015, 0x0100003e,
14914     };
14915     static const D3D12_SHADER_BYTECODE ps_2d_array = {ps_2d_array_code, sizeof(ps_2d_array_code)};
14916     static const DWORD ps_3d_code[] =
14917     {
14918 #if 0
14919         Texture3D t;
14920 
14921         uint type;
14922         uint level;
14923 
14924         float4 main() : SV_TARGET
14925         {
14926             if (!type)
14927             {
14928                 float width, height, depth, miplevels;
14929                 t.GetDimensions(level, width, height, depth, miplevels);
14930                 return float4(width, height, depth, miplevels);
14931             }
14932             else
14933             {
14934                 uint width, height, depth, miplevels;
14935                 t.GetDimensions(level, width, height, depth, miplevels);
14936                 return float4(width, height, depth, miplevels);
14937             }
14938         }
14939 #endif
14940         0x43425844, 0xac1f73b9, 0x2bce1322, 0x82c599e6, 0xbff0d681, 0x00000001, 0x0000012c, 0x00000003,
14941         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
14942         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
14943         0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x000000b4, 0x00000040, 0x0000002d,
14944         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04002858, 0x00107000, 0x00000000, 0x00005555,
14945         0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0400001f, 0x0020800a, 0x00000000,
14946         0x00000000, 0x0800003d, 0x001020f2, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x00107e46,
14947         0x00000000, 0x0100003e, 0x01000012, 0x0800103d, 0x001000f2, 0x00000000, 0x0020801a, 0x00000000,
14948         0x00000000, 0x00107e46, 0x00000000, 0x05000056, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
14949         0x0100003e, 0x01000015, 0x0100003e,
14950     };
14951     static const D3D12_SHADER_BYTECODE ps_3d = {ps_3d_code, sizeof(ps_3d_code)};
14952     static const DWORD ps_cube_code[] =
14953     {
14954 #if 0
14955         TextureCube t;
14956 
14957         uint type;
14958         uint level;
14959 
14960         float4 main() : SV_TARGET
14961         {
14962             if (!type)
14963             {
14964                 float width, height, miplevels;
14965                 t.GetDimensions(level, width, height, miplevels);
14966                 return float4(width, height, miplevels, 0);
14967             }
14968             else
14969             {
14970                 uint width, height, miplevels;
14971                 t.GetDimensions(level, width, height, miplevels);
14972                 return float4(width, height, miplevels, 0);
14973             }
14974         }
14975 #endif
14976         0x43425844, 0x795eb161, 0xb8291400, 0xcc531086, 0x2a8143ce, 0x00000001, 0x00000168, 0x00000003,
14977         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
14978         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
14979         0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x000000f0, 0x00000040, 0x0000003c,
14980         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04003058, 0x00107000, 0x00000000, 0x00005555,
14981         0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0400001f, 0x0020800a, 0x00000000,
14982         0x00000000, 0x0800003d, 0x001000f2, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x00107e46,
14983         0x00000000, 0x05000036, 0x00102072, 0x00000000, 0x00100346, 0x00000000, 0x05000036, 0x00102082,
14984         0x00000000, 0x00004001, 0x00000000, 0x0100003e, 0x01000012, 0x0800103d, 0x001000f2, 0x00000000,
14985         0x0020801a, 0x00000000, 0x00000000, 0x00107e46, 0x00000000, 0x05000056, 0x00102072, 0x00000000,
14986         0x00100346, 0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x00004001, 0x00000000, 0x0100003e,
14987         0x01000015, 0x0100003e,
14988     };
14989     static const D3D12_SHADER_BYTECODE ps_cube = {ps_cube_code, sizeof(ps_cube_code)};
14990     static const DWORD ps_cube_array_code[] =
14991     {
14992 #if 0
14993         TextureCubeArray t;
14994 
14995         uint type;
14996         uint level;
14997 
14998         float4 main() : SV_TARGET
14999         {
15000             if (!type)
15001             {
15002                 float width, height, elements, miplevels;
15003                 t.GetDimensions(level, width, height, elements, miplevels);
15004                 return float4(width, height, miplevels, 0);
15005             }
15006             else
15007             {
15008                 uint width, height, elements, miplevels;
15009                 t.GetDimensions(level, width, height, elements, miplevels);
15010                 return float4(width, height, miplevels, 0);
15011             }
15012         }
15013 #endif
15014         0x43425844, 0x894d136f, 0xa1f5c746, 0xd771ac09, 0x6914e044, 0x00000001, 0x0000016c, 0x00000003,
15015         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
15016         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
15017         0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x000000f4, 0x00000041, 0x0000003d,
15018         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04005058, 0x00107000, 0x00000000,
15019         0x00005555, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0400001f, 0x0020800a,
15020         0x00000000, 0x00000000, 0x0800003d, 0x00100072, 0x00000000, 0x0020801a, 0x00000000, 0x00000000,
15021         0x00107b46, 0x00000000, 0x05000036, 0x00102072, 0x00000000, 0x00100246, 0x00000000, 0x05000036,
15022         0x00102082, 0x00000000, 0x00004001, 0x00000000, 0x0100003e, 0x01000012, 0x0800103d, 0x00100072,
15023         0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x00107b46, 0x00000000, 0x05000056, 0x00102072,
15024         0x00000000, 0x00100246, 0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x00004001, 0x00000000,
15025         0x0100003e, 0x01000015, 0x0100003e,
15026     };
15027     static const D3D12_SHADER_BYTECODE ps_cube_array = {ps_cube_array_code, sizeof(ps_cube_array_code)};
15028     static const struct ps_test
15029     {
15030         const D3D12_SHADER_BYTECODE *ps;
15031         struct
15032         {
15033             unsigned int width;
15034             unsigned int height;
15035             unsigned int depth;
15036             unsigned int miplevel_count;
15037             unsigned int array_size;
15038             unsigned int cube_count;
15039         } texture_desc;
15040         unsigned int miplevel;
15041         struct vec4 expected_result;
15042     }
15043     ps_tests[] =
15044     {
15045         {&ps_2d, {64, 64, 1, 1, 1, 0}, 0, {64.0f, 64.0f, 1.0f, 0.0f}},
15046         {&ps_2d, {32, 16, 1, 3, 1, 0}, 0, {32.0f, 16.0f, 3.0f, 0.0f}},
15047         {&ps_2d, {32, 16, 1, 3, 1, 0}, 1, {16.0f,  8.0f, 3.0f, 0.0f}},
15048         {&ps_2d, {32, 16, 1, 3, 1, 0}, 2, { 8.0f,  4.0f, 3.0f, 0.0f}},
15049 
15050         {&ps_2d_array, {64, 64, 1, 1, 6, 0}, 0, {64.0f, 64.0f, 6.0f, 1.0f}},
15051         {&ps_2d_array, {32, 16, 1, 3, 9, 0}, 0, {32.0f, 16.0f, 9.0f, 3.0f}},
15052         {&ps_2d_array, {32, 16, 1, 3, 7, 0}, 1, {16.0f,  8.0f, 7.0f, 3.0f}},
15053         {&ps_2d_array, {32, 16, 1, 3, 3, 0}, 2, { 8.0f,  4.0f, 3.0f, 3.0f}},
15054 
15055         {&ps_3d, {64, 64, 2, 1, 1, 0}, 0, {64.0f, 64.0f, 2.0f, 1.0f}},
15056         {&ps_3d, {64, 64, 2, 2, 1, 0}, 1, {32.0f, 32.0f, 1.0f, 2.0f}},
15057         {&ps_3d, {64, 64, 4, 1, 1, 0}, 0, {64.0f, 64.0f, 4.0f, 1.0f}},
15058         {&ps_3d, {64, 64, 4, 2, 1, 0}, 1, {32.0f, 32.0f, 2.0f, 2.0f}},
15059         {&ps_3d, { 8,  8, 8, 1, 1, 0}, 0, { 8.0f,  8.0f, 8.0f, 1.0f}},
15060         {&ps_3d, { 8,  8, 8, 4, 1, 0}, 0, { 8.0f,  8.0f, 8.0f, 4.0f}},
15061         {&ps_3d, { 8,  8, 8, 4, 1, 0}, 1, { 4.0f,  4.0f, 4.0f, 4.0f}},
15062         {&ps_3d, { 8,  8, 8, 4, 1, 0}, 2, { 2.0f,  2.0f, 2.0f, 4.0f}},
15063         {&ps_3d, { 8,  8, 8, 4, 1, 0}, 3, { 1.0f,  1.0f, 1.0f, 4.0f}},
15064 
15065         {&ps_cube, { 4,  4, 1, 1, 6, 1}, 0, { 4.0f,  4.0f, 1.0f, 0.0f}},
15066         {&ps_cube, {32, 32, 1, 1, 6, 1}, 0, {32.0f, 32.0f, 1.0f, 0.0f}},
15067         {&ps_cube, {32, 32, 1, 3, 6, 1}, 0, {32.0f, 32.0f, 3.0f, 0.0f}},
15068         {&ps_cube, {32, 32, 1, 3, 6, 1}, 1, {16.0f, 16.0f, 3.0f, 0.0f}},
15069         {&ps_cube, {32, 32, 1, 3, 6, 1}, 2, { 8.0f,  8.0f, 3.0f, 0.0f}},
15070 
15071         {&ps_cube_array, { 4,  4, 1, 1, 12, 2}, 0, { 4.0f,  4.0f, 1.0f, 0.0f}},
15072         {&ps_cube_array, {32, 32, 1, 1, 12, 2}, 0, {32.0f, 32.0f, 1.0f, 0.0f}},
15073         {&ps_cube_array, {32, 32, 1, 3, 12, 2}, 0, {32.0f, 32.0f, 3.0f, 0.0f}},
15074     };
15075 
15076     memset(&desc, 0, sizeof(desc));
15077     desc.rt_width = desc.rt_height = 64;
15078     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
15079     desc.no_root_signature = true;
15080     if (!init_test_context(&context, &desc))
15081         return;
15082     device = context.device;
15083     command_list = context.list;
15084     queue = context.queue;
15085 
15086     context.root_signature = create_texture_root_signature(context.device,
15087             D3D12_SHADER_VISIBILITY_PIXEL, 4, 0);
15088 
15089     heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 6);
15090     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
15091 
15092     current_ps = NULL;
15093     for (i = 0; i < ARRAY_SIZE(ps_tests); ++i)
15094     {
15095         const struct ps_test *test = &ps_tests[i];
15096 
15097         vkd3d_test_set_context("test %u", i);
15098 
15099         if (current_ps != test->ps)
15100         {
15101             if (context.pipeline_state)
15102                 ID3D12PipelineState_Release(context.pipeline_state);
15103 
15104             current_ps = test->ps;
15105 
15106             context.pipeline_state = create_pipeline_state(context.device,
15107                     context.root_signature, context.render_target_desc.Format, NULL, current_ps, NULL);
15108         }
15109 
15110         memset(&heap_properties, 0, sizeof(heap_properties));
15111         heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
15112         resource_desc.Dimension = test->texture_desc.depth != 1
15113                 ? D3D12_RESOURCE_DIMENSION_TEXTURE3D : D3D12_RESOURCE_DIMENSION_TEXTURE2D;
15114         resource_desc.Alignment = 0;
15115         resource_desc.Width = test->texture_desc.width;
15116         resource_desc.Height = test->texture_desc.height;
15117         resource_desc.DepthOrArraySize = test->texture_desc.depth != 1
15118                 ? test->texture_desc.depth : test->texture_desc.array_size;
15119         resource_desc.MipLevels = test->texture_desc.miplevel_count;
15120         resource_desc.Format = DXGI_FORMAT_R8_UNORM;
15121         resource_desc.SampleDesc.Count = 1;
15122         resource_desc.SampleDesc.Quality = 0;
15123         resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
15124         resource_desc.Flags = 0;
15125         hr = ID3D12Device_CreateCommittedResource(device,
15126                 &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
15127                 D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, NULL,
15128                 &IID_ID3D12Resource, (void **)&texture);
15129         ok(hr == S_OK, "Test %u: Failed to create texture, hr %#x.\n", i, hr);
15130 
15131         current_srv_desc = NULL;
15132         if (test->texture_desc.cube_count)
15133         {
15134             current_srv_desc = &srv_desc;
15135             srv_desc.Format = resource_desc.Format;
15136             srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
15137             if (test->texture_desc.cube_count > 1)
15138             {
15139                 srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
15140                 srv_desc.TextureCubeArray.MostDetailedMip = 0;
15141                 srv_desc.TextureCubeArray.MipLevels = resource_desc.MipLevels;
15142                 srv_desc.TextureCubeArray.First2DArrayFace = 0;
15143                 srv_desc.TextureCubeArray.NumCubes = test->texture_desc.cube_count;
15144                 srv_desc.TextureCubeArray.ResourceMinLODClamp = 0.0f;
15145             }
15146             else
15147             {
15148                 srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
15149                 srv_desc.TextureCube.MostDetailedMip = 0;
15150                 srv_desc.TextureCube.MipLevels = resource_desc.MipLevels;
15151                 srv_desc.TextureCube.ResourceMinLODClamp = 0.0f;
15152             }
15153         }
15154         ID3D12Device_CreateShaderResourceView(context.device, texture, current_srv_desc, cpu_handle);
15155 
15156         for (type = 0; type < 2; ++type)
15157         {
15158             vkd3d_test_set_context("test %u, type %u", i, type);
15159 
15160             memset(&constant, 0, sizeof(constant));
15161             constant.x = type;
15162             constant.y = test->miplevel;
15163 
15164             ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
15165             ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
15166             ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
15167             ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
15168             ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
15169             ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
15170             ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
15171             ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
15172                     get_gpu_descriptor_handle(&context, heap, 0));
15173             ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &constant.x, 0);
15174             ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
15175 
15176             transition_resource_state(command_list, context.render_target,
15177                     D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
15178 
15179             check_sub_resource_vec4(context.render_target, 0, queue, command_list, &test->expected_result, 0);
15180 
15181             reset_command_list(command_list, context.allocator);
15182             transition_resource_state(command_list, context.render_target,
15183                     D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
15184         }
15185 
15186         ID3D12Resource_Release(texture);
15187     }
15188     vkd3d_test_set_context(NULL);
15189 
15190     ID3D12DescriptorHeap_Release(heap);
15191     destroy_test_context(&context);
15192 }
15193 
test_srv_component_mapping(void)15194 static void test_srv_component_mapping(void)
15195 {
15196     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
15197     D3D12_SUBRESOURCE_DATA subresource_data;
15198     ID3D12GraphicsCommandList *command_list;
15199     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
15200     D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
15201     struct test_context_desc desc;
15202     struct test_context context;
15203     ID3D12DescriptorHeap *heap;
15204     ID3D12CommandQueue *queue;
15205     ID3D12Resource *texture;
15206     uint32_t expected_color;
15207     unsigned int i, j;
15208 
15209     static const DWORD ps_code[] =
15210     {
15211 #if 0
15212         Texture2D t;
15213         SamplerState s;
15214 
15215         float4 main(float4 position : SV_POSITION) : SV_Target
15216         {
15217             float2 p;
15218         D3D12_SUBRESOURCE_DATA data;
15219 
15220             p.x = position.x / 32.0f;
15221             p.y = position.y / 32.0f;
15222             return t.Sample(s, p);
15223         }
15224 #endif
15225         0x43425844, 0x7a0c3929, 0x75ff3ca4, 0xccb318b2, 0xe6965b4c, 0x00000001, 0x00000140, 0x00000003,
15226         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
15227         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
15228         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
15229         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000a4, 0x00000050,
15230         0x00000029, 0x0100086a, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000,
15231         0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
15232         0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002,
15233         0x3d000000, 0x3d000000, 0x00000000, 0x00000000, 0x8b000045, 0x800000c2, 0x00155543, 0x001020f2,
15234         0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0100003e,
15235     };
15236     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
15237     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
15238     static const uint32_t r8g8b8a8_data = 0x39495969;
15239     static const uint16_t r8g8_data = 0xaabb;
15240     static const uint8_t a8_data = 0x11;
15241     static const uint8_t r8_data = 0xfe;
15242     static const struct
15243     {
15244         const char *name;
15245         DXGI_FORMAT format;
15246         const void *data;
15247         uint32_t color;
15248     }
15249     tests[] =
15250     {
15251         {"R8G8B8A8", DXGI_FORMAT_R8G8B8A8_UNORM, &r8g8b8a8_data, 0x39495969},
15252         {"R8G8",     DXGI_FORMAT_R8G8_UNORM,     &r8g8_data,     0xff00aabb},
15253         {"R8",       DXGI_FORMAT_R8_UNORM,       &r8_data,       0xff0000fe},
15254         {"A8",       DXGI_FORMAT_A8_UNORM,       &a8_data,       0x11000000},
15255     };
15256     static const struct
15257     {
15258         unsigned int mapping;
15259         unsigned int r_shift;
15260         unsigned int g_shift;
15261         unsigned int b_shift;
15262         unsigned int a_shift;
15263         uint32_t forced_mask;
15264         uint32_t forced_color;
15265     }
15266     component_mappings[] =
15267     {
15268         {
15269             D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
15270                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
15271                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
15272                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
15273                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0),
15274             0, 0, 0, 0, 0xffffffff, 0x00000000,
15275         },
15276         {
15277             D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
15278                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1,
15279                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1,
15280                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1,
15281                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1),
15282             0, 0, 0, 0, 0xffffffff, 0xffffffff,
15283         },
15284         {
15285             D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
15286                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1,
15287                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
15288                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
15289                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1),
15290             0, 0, 0, 0, 0xffffffff, 0xff0000ff,
15291         },
15292         {
15293             D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
15294                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1,
15295                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
15296                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1,
15297                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0),
15298             0, 0, 0, 0, 0xffffffff, 0x00ff00ff,
15299         },
15300 
15301         {
15302             D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
15303                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0,
15304                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
15305                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2,
15306                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3),
15307             0, 8, 16, 24, 0x00000000, 0x00000000,
15308         },
15309         {
15310             D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
15311                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3,
15312                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2,
15313                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
15314                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0),
15315             24, 16, 8, 0, 0x00000000, 0x00000000,
15316         },
15317 
15318         {
15319             D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
15320                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0,
15321                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
15322                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2,
15323                     D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0),
15324             0, 8, 16, 24, 0xff000000, 0x00000000,
15325         },
15326 
15327         {
15328             D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
15329                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0,
15330                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0,
15331                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0,
15332                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0),
15333             0, 0, 0, 0, 0x00000000, 0x00000000,
15334         },
15335         {
15336             D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
15337                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
15338                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
15339                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
15340                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1),
15341             8, 8, 8, 8, 0x00000000, 0x00000000,
15342         },
15343         {
15344             D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
15345                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2,
15346                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2,
15347                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2,
15348                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2),
15349             16, 16, 16, 16, 0x00000000, 0x00000000,
15350         },
15351         {
15352             D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
15353                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3,
15354                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3,
15355                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3,
15356                     D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3),
15357             24, 24, 24, 24, 0x00000000, 0x00000000,
15358         },
15359     };
15360 
15361     memset(&desc, 0, sizeof(desc));
15362     desc.rt_width = desc.rt_height = 32;
15363     desc.no_root_signature = true;
15364     if (!init_test_context(&context, &desc))
15365         return;
15366     command_list = context.list;
15367     queue = context.queue;
15368 
15369     context.root_signature = create_texture_root_signature(context.device,
15370             D3D12_SHADER_VISIBILITY_PIXEL, 0, 0);
15371     context.pipeline_state = create_pipeline_state(context.device,
15372             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
15373 
15374     heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
15375     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
15376     gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
15377 
15378     for (i = 0; i < ARRAY_SIZE(tests); ++i)
15379     {
15380         vkd3d_test_set_context("Test %s", tests[i].name);
15381 
15382         texture = create_default_texture(context.device, 1, 1,
15383                 tests[i].format, 0, D3D12_RESOURCE_STATE_COPY_DEST);
15384         subresource_data.pData = tests[i].data;
15385         subresource_data.RowPitch = format_size(tests[i].format);
15386         subresource_data.SlicePitch = subresource_data.RowPitch;
15387         upload_texture_data(texture, &subresource_data, 1, queue, command_list);
15388         reset_command_list(command_list, context.allocator);
15389 
15390         transition_resource_state(command_list, texture,
15391                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
15392 
15393         for (j = 0; j < ARRAY_SIZE(component_mappings); ++j)
15394         {
15395             vkd3d_test_set_context("Test %s, %u", tests[i].name, j);
15396 
15397             memset(&srv_desc, 0, sizeof(srv_desc));
15398             srv_desc.Format = tests[i].format;
15399             srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
15400             srv_desc.Shader4ComponentMapping = component_mappings[j].mapping;
15401             srv_desc.Texture2D.MipLevels = 1;
15402             ID3D12Device_CreateShaderResourceView(context.device, texture, &srv_desc, cpu_handle);
15403 
15404             ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
15405 
15406             ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
15407             ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
15408             ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
15409             ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
15410             ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
15411             ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
15412             ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
15413             ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
15414             ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
15415 
15416             transition_resource_state(command_list, context.render_target,
15417                     D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
15418             expected_color = 0;
15419             expected_color |= ((tests[i].color >> component_mappings[j].r_shift) & 0xff) << 0;
15420             expected_color |= ((tests[i].color >> component_mappings[j].g_shift) & 0xff) << 8;
15421             expected_color |= ((tests[i].color >> component_mappings[j].b_shift) & 0xff) << 16;
15422             expected_color |= ((tests[i].color >> component_mappings[j].a_shift) & 0xff) << 24;
15423             expected_color &= ~component_mappings[j].forced_mask;
15424             expected_color |= component_mappings[j].forced_color & component_mappings[j].forced_mask;
15425             check_sub_resource_uint(context.render_target, 0, queue, command_list, expected_color, 0);
15426 
15427             reset_command_list(command_list, context.allocator);
15428             transition_resource_state(command_list, context.render_target,
15429                     D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
15430         }
15431 
15432         ID3D12Resource_Release(texture);
15433     }
15434     vkd3d_test_set_context(NULL);
15435 
15436     ID3D12DescriptorHeap_Release(heap);
15437     destroy_test_context(&context);
15438 }
15439 
test_descriptor_tables(void)15440 static void test_descriptor_tables(void)
15441 {
15442     ID3D12DescriptorHeap *heap, *sampler_heap, *heaps[2];
15443     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
15444     D3D12_DESCRIPTOR_RANGE descriptor_range[4];
15445     D3D12_CONSTANT_BUFFER_VIEW_DESC cbv_desc;
15446     D3D12_ROOT_PARAMETER root_parameters[3];
15447     ID3D12GraphicsCommandList *command_list;
15448     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
15449     D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
15450     ID3D12Resource *cb, *textures[4];
15451     unsigned int i, descriptor_size;
15452     D3D12_SAMPLER_DESC sampler_desc;
15453     struct test_context_desc desc;
15454     D3D12_SUBRESOURCE_DATA data;
15455     struct test_context context;
15456     ID3D12CommandQueue *queue;
15457     HRESULT hr;
15458 
15459     static const DWORD ps_code[] =
15460     {
15461 #if 0
15462         Texture2D t0;
15463         Texture2D t1;
15464         Texture2D t2;
15465         Texture2D t3;
15466         SamplerState s0;
15467 
15468         cbuffer cb0
15469         {
15470             float4 c;
15471         };
15472 
15473         float4 main(float4 position : SV_POSITION) : SV_Target
15474         {
15475             float2 p = float2(position.x / 32.0f, position.y / 32.0f);
15476 
15477             return c.x * t0.Sample(s0, p) + c.y * t1.Sample(s0, p)
15478                     + c.z * t2.Sample(s0, p) + c.w * t3.Sample(s0, p);
15479         }
15480 #endif
15481         0x43425844, 0xf848ef5f, 0x4da3fe0c, 0x776883a0, 0x6b3f0297, 0x00000001, 0x0000029c, 0x00000003,
15482         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
15483         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
15484         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
15485         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000200, 0x00000050,
15486         0x00000080, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000,
15487         0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001,
15488         0x00005555, 0x04001858, 0x00107000, 0x00000002, 0x00005555, 0x04001858, 0x00107000, 0x00000003,
15489         0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
15490         0x02000068, 0x00000003, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002,
15491         0x3d000000, 0x3d000000, 0x00000000, 0x00000000, 0x8b000045, 0x800000c2, 0x00155543, 0x001000f2,
15492         0x00000001, 0x00100046, 0x00000000, 0x00107e46, 0x00000001, 0x00106000, 0x00000000, 0x08000038,
15493         0x001000f2, 0x00000001, 0x00100e46, 0x00000001, 0x00208556, 0x00000000, 0x00000000, 0x8b000045,
15494         0x800000c2, 0x00155543, 0x001000f2, 0x00000002, 0x00100046, 0x00000000, 0x00107e46, 0x00000000,
15495         0x00106000, 0x00000000, 0x0a000032, 0x001000f2, 0x00000001, 0x00208006, 0x00000000, 0x00000000,
15496         0x00100e46, 0x00000002, 0x00100e46, 0x00000001, 0x8b000045, 0x800000c2, 0x00155543, 0x001000f2,
15497         0x00000002, 0x00100046, 0x00000000, 0x00107e46, 0x00000002, 0x00106000, 0x00000000, 0x8b000045,
15498         0x800000c2, 0x00155543, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000003,
15499         0x00106000, 0x00000000, 0x0a000032, 0x001000f2, 0x00000001, 0x00208aa6, 0x00000000, 0x00000000,
15500         0x00100e46, 0x00000002, 0x00100e46, 0x00000001, 0x0a000032, 0x001020f2, 0x00000000, 0x00208ff6,
15501         0x00000000, 0x00000000, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x0100003e,
15502     };
15503     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
15504     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
15505     static const struct vec4 constant = {0.1f, 0.2f, 0.3f, 0.1f};
15506     static const unsigned int texture_data[4] = {0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffff00};
15507 
15508     memset(&desc, 0, sizeof(desc));
15509     desc.no_root_signature = true;
15510     if (!init_test_context(&context, &desc))
15511         return;
15512     command_list = context.list;
15513     queue = context.queue;
15514 
15515     cb = create_upload_buffer(context.device, sizeof(constant), &constant.x);
15516 
15517     descriptor_range[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
15518     descriptor_range[0].NumDescriptors = 2;
15519     descriptor_range[0].BaseShaderRegister = 0;
15520     descriptor_range[0].RegisterSpace = 0;
15521     descriptor_range[0].OffsetInDescriptorsFromTableStart = 1;
15522     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
15523     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
15524     root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_range[0];
15525     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
15526 
15527     descriptor_range[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
15528     descriptor_range[1].NumDescriptors = 1;
15529     descriptor_range[1].BaseShaderRegister = 0;
15530     descriptor_range[1].RegisterSpace = 0;
15531     descriptor_range[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
15532     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
15533     root_parameters[1].DescriptorTable.NumDescriptorRanges = 1;
15534     root_parameters[1].DescriptorTable.pDescriptorRanges = &descriptor_range[1];
15535     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
15536 
15537     descriptor_range[2].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
15538     descriptor_range[2].NumDescriptors = 2;
15539     descriptor_range[2].BaseShaderRegister = 2;
15540     descriptor_range[2].RegisterSpace = 0;
15541     descriptor_range[2].OffsetInDescriptorsFromTableStart = 0;
15542     descriptor_range[3].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
15543     descriptor_range[3].NumDescriptors = 1;
15544     descriptor_range[3].BaseShaderRegister = 0;
15545     descriptor_range[3].RegisterSpace = 0;
15546     descriptor_range[3].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
15547     root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
15548     root_parameters[2].DescriptorTable.NumDescriptorRanges = 2;
15549     root_parameters[2].DescriptorTable.pDescriptorRanges = &descriptor_range[2];
15550     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
15551 
15552     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
15553     root_signature_desc.NumParameters = 3;
15554     root_signature_desc.pParameters = root_parameters;
15555     hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
15556     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
15557 
15558     context.pipeline_state = create_pipeline_state(context.device,
15559             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
15560 
15561     memset(&sampler_desc, 0, sizeof(sampler_desc));
15562     sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
15563     sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
15564     sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
15565     sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
15566 
15567     heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 6);
15568     sampler_heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 1);
15569 
15570     descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(context.device,
15571             D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
15572 
15573     for (i = 0; i < ARRAY_SIZE(textures); ++i)
15574     {
15575         textures[i] = create_default_texture(context.device,
15576                 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D12_RESOURCE_STATE_COPY_DEST);
15577         data.pData = &texture_data[i];
15578         data.RowPitch = sizeof(texture_data[i]);
15579         data.SlicePitch = data.RowPitch;
15580         upload_texture_data(textures[i], &data, 1, queue, command_list);
15581         reset_command_list(command_list, context.allocator);
15582     }
15583 
15584     for (i = 0; i < ARRAY_SIZE(textures); ++i)
15585         transition_resource_state(command_list, textures[i],
15586                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
15587 
15588     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
15589     cpu_handle.ptr += descriptor_size;
15590     /* t0-t3 */
15591     for (i = 0; i < ARRAY_SIZE(textures); ++i)
15592     {
15593         ID3D12Device_CreateShaderResourceView(context.device, textures[i], NULL, cpu_handle);
15594         cpu_handle.ptr += descriptor_size;
15595     }
15596     /* cbv0 */
15597     cbv_desc.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(cb);
15598     cbv_desc.SizeInBytes = align(sizeof(constant), D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT);
15599     ID3D12Device_CreateConstantBufferView(context.device, &cbv_desc, cpu_handle);
15600 
15601     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(sampler_heap);
15602     /* s0 */
15603     ID3D12Device_CreateSampler(context.device, &sampler_desc, cpu_handle);
15604 
15605     gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
15606 
15607     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
15608 
15609     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
15610     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
15611     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
15612     heaps[0] = heap; heaps[1] = sampler_heap;
15613     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, ARRAY_SIZE(heaps), heaps);
15614     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
15615     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 1,
15616             ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(sampler_heap));
15617     gpu_handle.ptr += 3 * descriptor_size;
15618     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 2, gpu_handle);
15619     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
15620     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
15621     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
15622     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
15623 
15624     transition_resource_state(command_list, context.render_target,
15625             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
15626     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xb2664c19, 2);
15627 
15628     ID3D12Resource_Release(cb);
15629     for (i = 0; i < ARRAY_SIZE(textures); ++i)
15630         ID3D12Resource_Release(textures[i]);
15631     ID3D12DescriptorHeap_Release(heap);
15632     ID3D12DescriptorHeap_Release(sampler_heap);
15633     destroy_test_context(&context);
15634 }
15635 
15636 /* Tests overlapping descriptor heap ranges for SRV and UAV descriptor tables.
15637  * Only descriptors used by the pipeline have to be valid.
15638  */
test_descriptor_tables_overlapping_bindings(void)15639 static void test_descriptor_tables_overlapping_bindings(void)
15640 {
15641     ID3D12Resource *input_buffers[2], *output_buffers[2];
15642     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
15643     D3D12_DESCRIPTOR_RANGE descriptor_range[2];
15644     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
15645     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
15646     D3D12_ROOT_PARAMETER root_parameters[3];
15647     ID3D12GraphicsCommandList *command_list;
15648     struct resource_readback rb;
15649     struct test_context context;
15650     ID3D12DescriptorHeap *heap;
15651     ID3D12CommandQueue *queue;
15652     ID3D12Device *device;
15653     unsigned int i;
15654     HRESULT hr;
15655 
15656     static const DWORD cs_code[] =
15657     {
15658 #if 0
15659         ByteAddressBuffer t0;
15660         ByteAddressBuffer t4 : register(t4);
15661 
15662         RWByteAddressBuffer u0;
15663         RWByteAddressBuffer u2 : register(u2);
15664 
15665         uint size;
15666         uint size2;
15667 
15668         [numthreads(1, 1, 1)]
15669         void main()
15670         {
15671             uint i;
15672             for (i = 0; i < size; ++i)
15673                 u0.Store(4 * i, t0.Load(4 *i));
15674             for (i = 0; i < size2; ++i)
15675                 u2.Store(4 * i, t4.Load(4 * i));
15676         }
15677 #endif
15678         0x43425844, 0x8d2646b7, 0xeb60d9ee, 0x33ccd6ed, 0x5557e649, 0x00000001, 0x0000023c, 0x00000003,
15679         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
15680         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000001e8, 0x00050050, 0x0000007a, 0x0100086a,
15681         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x030000a1, 0x00107000, 0x00000000, 0x030000a1,
15682         0x00107000, 0x00000004, 0x0300009d, 0x0011e000, 0x00000000, 0x0300009d, 0x0011e000, 0x00000002,
15683         0x02000068, 0x00000001, 0x0400009b, 0x00000001, 0x00000001, 0x00000001, 0x05000036, 0x00100012,
15684         0x00000000, 0x00004001, 0x00000000, 0x01000030, 0x08000050, 0x00100022, 0x00000000, 0x0010000a,
15685         0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x03040003, 0x0010001a, 0x00000000, 0x07000029,
15686         0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000002, 0x890000a5, 0x800002c2,
15687         0x00199983, 0x00100042, 0x00000000, 0x0010001a, 0x00000000, 0x00107006, 0x00000000, 0x070000a6,
15688         0x0011e012, 0x00000000, 0x0010001a, 0x00000000, 0x0010002a, 0x00000000, 0x0700001e, 0x00100012,
15689         0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000001, 0x01000016, 0x05000036, 0x00100012,
15690         0x00000000, 0x00004001, 0x00000000, 0x01000030, 0x08000050, 0x00100022, 0x00000000, 0x0010000a,
15691         0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x03040003, 0x0010001a, 0x00000000, 0x07000029,
15692         0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000002, 0x890000a5, 0x800002c2,
15693         0x00199983, 0x00100042, 0x00000000, 0x0010001a, 0x00000000, 0x00107006, 0x00000004, 0x070000a6,
15694         0x0011e012, 0x00000002, 0x0010001a, 0x00000000, 0x0010002a, 0x00000000, 0x0700001e, 0x00100012,
15695         0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000001, 0x01000016, 0x0100003e,
15696     };
15697     static const uint32_t buffer_data[] = {0xdeadbabe};
15698     static const uint32_t buffer_data2[] = {0, 1, 2, 3, 4, 5};
15699 
15700     if (!init_compute_test_context(&context))
15701         return;
15702     device = context.device;
15703     command_list = context.list;
15704     queue = context.queue;
15705 
15706     descriptor_range[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
15707     descriptor_range[0].NumDescriptors = 10;
15708     descriptor_range[0].BaseShaderRegister = 0;
15709     descriptor_range[0].RegisterSpace = 0;
15710     descriptor_range[0].OffsetInDescriptorsFromTableStart = 0;
15711     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
15712     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
15713     root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_range[0];
15714     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
15715 
15716     descriptor_range[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
15717     descriptor_range[1].NumDescriptors = 10;
15718     descriptor_range[1].BaseShaderRegister = 0;
15719     descriptor_range[1].RegisterSpace = 0;
15720     descriptor_range[1].OffsetInDescriptorsFromTableStart = 0;
15721     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
15722     root_parameters[1].DescriptorTable.NumDescriptorRanges = 1;
15723     root_parameters[1].DescriptorTable.pDescriptorRanges = &descriptor_range[1];
15724     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
15725 
15726     root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
15727     root_parameters[2].Constants.ShaderRegister = 0;
15728     root_parameters[2].Constants.RegisterSpace = 0;
15729     root_parameters[2].Constants.Num32BitValues = 2;
15730     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
15731 
15732     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
15733     root_signature_desc.NumParameters = 3;
15734     root_signature_desc.pParameters = root_parameters;
15735     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
15736     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
15737 
15738     context.pipeline_state = create_compute_pipeline_state(device, context.root_signature,
15739             shader_bytecode(cs_code, sizeof(cs_code)));
15740 
15741     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 30);
15742 
15743     input_buffers[0] = create_default_buffer(device, sizeof(buffer_data),
15744             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
15745     upload_buffer_data(input_buffers[0], 0, sizeof(buffer_data), &buffer_data, queue, command_list);
15746     reset_command_list(command_list, context.allocator);
15747     transition_resource_state(command_list, input_buffers[0],
15748             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
15749 
15750     input_buffers[1] = create_default_buffer(device, sizeof(buffer_data2),
15751             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
15752     upload_buffer_data(input_buffers[1], 0, sizeof(buffer_data2), &buffer_data2, queue, command_list);
15753     reset_command_list(command_list, context.allocator);
15754     transition_resource_state(command_list, input_buffers[1],
15755             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
15756 
15757     output_buffers[0] = create_default_buffer(device, sizeof(buffer_data),
15758               D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
15759     output_buffers[1] = create_default_buffer(device, sizeof(buffer_data2),
15760             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
15761 
15762     memset(&uav_desc, 0, sizeof(uav_desc));
15763     uav_desc.Format = DXGI_FORMAT_R32_TYPELESS;
15764     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
15765     uav_desc.Buffer.FirstElement = 0;
15766     uav_desc.Buffer.NumElements = ARRAY_SIZE(buffer_data);
15767     uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
15768     ID3D12Device_CreateUnorderedAccessView(device, output_buffers[0], NULL, &uav_desc,
15769             get_cpu_descriptor_handle(&context, heap, 0)); /* u0 */
15770     uav_desc.Buffer.NumElements = ARRAY_SIZE(buffer_data2);
15771     ID3D12Device_CreateUnorderedAccessView(device, output_buffers[1], NULL, &uav_desc,
15772             get_cpu_descriptor_handle(&context, heap, 2)); /* u2 */
15773 
15774     memset(&srv_desc, 0, sizeof(srv_desc));
15775     srv_desc.Format = DXGI_FORMAT_R32_TYPELESS;
15776     srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
15777     srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
15778     srv_desc.Buffer.FirstElement = 0;
15779     srv_desc.Buffer.NumElements = ARRAY_SIZE(buffer_data);
15780     srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
15781     ID3D12Device_CreateShaderResourceView(device, input_buffers[0], &srv_desc,
15782             get_cpu_descriptor_handle(&context, heap, 3)); /* t0 */
15783     srv_desc.Buffer.NumElements = ARRAY_SIZE(buffer_data2);
15784     ID3D12Device_CreateShaderResourceView(device, input_buffers[1], &srv_desc,
15785             get_cpu_descriptor_handle(&context, heap, 7)); /* t4 */
15786 
15787     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
15788     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
15789     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
15790     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0,
15791             get_gpu_descriptor_handle(&context, heap, 3));
15792     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 1,
15793             get_gpu_descriptor_handle(&context, heap, 0));
15794     ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(command_list, 2,
15795             ARRAY_SIZE(buffer_data), 0);
15796     ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(command_list, 2,
15797             ARRAY_SIZE(buffer_data2), 1);
15798     ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
15799 
15800     for (i = 0; i < ARRAY_SIZE(output_buffers); ++i)
15801     {
15802         transition_resource_state(command_list, output_buffers[i],
15803                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
15804     }
15805 
15806     get_buffer_readback_with_command_list(output_buffers[0], DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
15807     for (i = 0; i < ARRAY_SIZE(buffer_data); ++i)
15808     {
15809         unsigned int value = get_readback_uint(&rb, i, 0, 0);
15810         ok(value == buffer_data[i], "Got %#x, expected %#x.\n", value, buffer_data[i]);
15811     }
15812     release_resource_readback(&rb);
15813     reset_command_list(command_list, context.allocator);
15814     get_buffer_readback_with_command_list(output_buffers[1], DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
15815     for (i = 0; i < ARRAY_SIZE(buffer_data2); ++i)
15816     {
15817         unsigned int value = get_readback_uint(&rb, i, 0, 0);
15818         ok(value == buffer_data2[i], "Got %#x, expected %#x.\n", value, buffer_data2[i]);
15819     }
15820     release_resource_readback(&rb);
15821 
15822     for (i = 0; i < ARRAY_SIZE(input_buffers); ++i)
15823         ID3D12Resource_Release(input_buffers[i]);
15824     for (i = 0; i < ARRAY_SIZE(output_buffers); ++i)
15825         ID3D12Resource_Release(output_buffers[i]);
15826     ID3D12DescriptorHeap_Release(heap);
15827     destroy_test_context(&context);
15828 }
15829 
test_update_root_descriptors(void)15830 static void test_update_root_descriptors(void)
15831 {
15832     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
15833     D3D12_GPU_VIRTUAL_ADDRESS cb_va, uav_va;
15834     D3D12_ROOT_PARAMETER root_parameters[2];
15835     ID3D12GraphicsCommandList *command_list;
15836     ID3D12RootSignature *root_signature;
15837     ID3D12PipelineState *pipeline_state;
15838     ID3D12Resource *resource, *cb;
15839     struct resource_readback rb;
15840     struct test_context context;
15841     ID3D12CommandQueue *queue;
15842     ID3D12Device *device;
15843     unsigned int i;
15844     HRESULT hr;
15845 
15846     static const DWORD cs_code[] =
15847     {
15848 #if 0
15849         cbuffer cb
15850         {
15851             unsigned int offset;
15852             unsigned int value;
15853         };
15854 
15855         RWByteAddressBuffer b;
15856 
15857         [numthreads(1, 1, 1)]
15858         void main()
15859         {
15860             b.Store(4 * offset, value);
15861         }
15862 #endif
15863         0x43425844, 0xaadc5460, 0x88c27e90, 0x2acacf4e, 0x4e06019a, 0x00000001, 0x000000d8, 0x00000003,
15864         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
15865         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000084, 0x00050050, 0x00000021, 0x0100086a,
15866         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300009d, 0x0011e000, 0x00000000, 0x02000068,
15867         0x00000001, 0x0400009b, 0x00000001, 0x00000001, 0x00000001, 0x08000029, 0x00100012, 0x00000000,
15868         0x0020800a, 0x00000000, 0x00000000, 0x00004001, 0x00000002, 0x080000a6, 0x0011e012, 0x00000000,
15869         0x0010000a, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x0100003e,
15870     };
15871     struct
15872     {
15873         uint32_t offset;
15874         uint32_t value;
15875         uint32_t uav_offset;
15876         uint8_t padding[D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 3 * sizeof(uint32_t)];
15877     }
15878     input[] =
15879     {
15880         {0, 4,  0},
15881         {2, 6,  0},
15882         {0, 5, 64},
15883         {7, 2, 64},
15884     };
15885 
15886     if (!init_compute_test_context(&context))
15887         return;
15888     device = context.device;
15889     command_list = context.list;
15890     queue = context.queue;
15891 
15892     cb = create_upload_buffer(context.device, sizeof(input), input);
15893     cb_va = ID3D12Resource_GetGPUVirtualAddress(cb);
15894 
15895     resource = create_default_buffer(device, 512,
15896             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
15897     uav_va = ID3D12Resource_GetGPUVirtualAddress(resource);
15898 
15899     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
15900     root_parameters[0].Descriptor.ShaderRegister = 0;
15901     root_parameters[0].Descriptor.RegisterSpace = 0;
15902     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
15903     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
15904     root_parameters[1].Descriptor.ShaderRegister = 0;
15905     root_parameters[1].Descriptor.RegisterSpace = 0;
15906     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
15907     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
15908     root_signature_desc.NumParameters = 2;
15909     root_signature_desc.pParameters = root_parameters;
15910     hr = create_root_signature(device, &root_signature_desc, &root_signature);
15911     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
15912 
15913     pipeline_state = create_compute_pipeline_state(device, root_signature,
15914             shader_bytecode(cs_code, sizeof(cs_code)));
15915 
15916     ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
15917     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, root_signature);
15918     for (i = 0; i < ARRAY_SIZE(input); ++i)
15919     {
15920         ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(command_list,
15921                 0, cb_va + i * sizeof(*input));
15922         if (!i || input[i - 1].uav_offset != input[i].uav_offset)
15923             ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list,
15924                     1, uav_va + input[i].uav_offset * sizeof(uint32_t));
15925         ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
15926     }
15927 
15928     transition_sub_resource_state(command_list, resource, 0,
15929             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
15930 
15931     get_buffer_readback_with_command_list(resource, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
15932     for (i = 0; i < ARRAY_SIZE(input); ++i)
15933     {
15934         unsigned int offset = input[i].uav_offset + input[i].offset;
15935         unsigned int value = get_readback_uint(&rb, offset, 0, 0);
15936         ok(value == input[i].value, "Got %#x, expected %#x.\n", value, input[i].value);
15937     }
15938     release_resource_readback(&rb);
15939 
15940     ID3D12Resource_Release(cb);
15941     ID3D12Resource_Release(resource);
15942     ID3D12RootSignature_Release(root_signature);
15943     ID3D12PipelineState_Release(pipeline_state);
15944     destroy_test_context(&context);
15945 }
15946 
test_update_descriptor_tables(void)15947 static void test_update_descriptor_tables(void)
15948 {
15949     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
15950     D3D12_DESCRIPTOR_RANGE descriptor_range;
15951     ID3D12GraphicsCommandList *command_list;
15952     D3D12_STATIC_SAMPLER_DESC sampler_desc;
15953     ID3D12DescriptorHeap *heap, *cpu_heap;
15954     D3D12_DESCRIPTOR_HEAP_DESC heap_desc;
15955     D3D12_ROOT_PARAMETER root_parameter;
15956     struct test_context_desc desc;
15957     D3D12_SUBRESOURCE_DATA data;
15958     struct resource_readback rb;
15959     struct test_context context;
15960     ID3D12Resource *textures[3];
15961     ID3D12CommandQueue *queue;
15962     unsigned int i;
15963     D3D12_BOX box;
15964     HRESULT hr;
15965     RECT rect;
15966 
15967     static const DWORD ps_code[] =
15968     {
15969 #if 0
15970         Texture2D t0;
15971         Texture2D t1;
15972         SamplerState s;
15973 
15974         float4 main(float4 position : SV_POSITION) : SV_Target
15975         {
15976             float2 p = (position.x / 32.0f, position.x / 32.0f);
15977             return float4(t0.Sample(s, p).r, t1.Sample(s, p).r, 0, 1);
15978         }
15979 #endif
15980         0x43425844, 0x5c19caa6, 0xd4fadb4f, 0xc9d6831e, 0x563b68b7, 0x00000001, 0x000001a4, 0x00000003,
15981         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
15982         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000010f, 0x505f5653, 0x5449534f, 0x004e4f49,
15983         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
15984         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000108, 0x00000050,
15985         0x00000042, 0x0100086a, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000,
15986         0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04002064, 0x00101012, 0x00000000,
15987         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x07000038, 0x00100012,
15988         0x00000000, 0x0010100a, 0x00000000, 0x00004001, 0x3d000000, 0x8b000045, 0x800000c2, 0x00155543,
15989         0x00100022, 0x00000000, 0x00100006, 0x00000000, 0x00107e16, 0x00000000, 0x00106000, 0x00000000,
15990         0x8b000045, 0x800000c2, 0x00155543, 0x00100012, 0x00000000, 0x00100006, 0x00000000, 0x00107e46,
15991         0x00000001, 0x00106000, 0x00000000, 0x05000036, 0x00102032, 0x00000000, 0x00100516, 0x00000000,
15992         0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,
15993         0x0100003e,
15994     };
15995     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
15996     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
15997     static const float texture_data[] = {0.5f, 0.25f, 0.1f};
15998 
15999     memset(&desc, 0, sizeof(desc));
16000     desc.no_root_signature = true;
16001     if (!init_test_context(&context, &desc))
16002         return;
16003     command_list = context.list;
16004     queue = context.queue;
16005 
16006     memset(&sampler_desc, 0, sizeof(sampler_desc));
16007     sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
16008     sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
16009     sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
16010     sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
16011     sampler_desc.ShaderRegister = 0;
16012     sampler_desc.RegisterSpace = 0;
16013     sampler_desc.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
16014 
16015     descriptor_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
16016     descriptor_range.NumDescriptors = 2;
16017     descriptor_range.BaseShaderRegister = 0;
16018     descriptor_range.RegisterSpace = 0;
16019     descriptor_range.OffsetInDescriptorsFromTableStart = 0;
16020     root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
16021     root_parameter.DescriptorTable.NumDescriptorRanges = 1;
16022     root_parameter.DescriptorTable.pDescriptorRanges = &descriptor_range;
16023     root_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
16024 
16025     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
16026     root_signature_desc.NumParameters = 1;
16027     root_signature_desc.pParameters = &root_parameter;
16028     root_signature_desc.NumStaticSamplers = 1;
16029     root_signature_desc.pStaticSamplers = &sampler_desc;
16030     hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
16031     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
16032 
16033     context.pipeline_state = create_pipeline_state(context.device,
16034             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
16035 
16036     memset(&heap_desc, 0, sizeof(heap_desc));
16037     heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
16038     heap_desc.NumDescriptors = 4;
16039     heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
16040     hr = ID3D12Device_CreateDescriptorHeap(context.device, &heap_desc,
16041             &IID_ID3D12DescriptorHeap, (void **)&heap);
16042     ok(SUCCEEDED(hr), "Failed to create descriptor heap, hr %#x.\n", hr);
16043 
16044     heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
16045     hr = ID3D12Device_CreateDescriptorHeap(context.device, &heap_desc,
16046             &IID_ID3D12DescriptorHeap, (void **)&cpu_heap);
16047     ok(SUCCEEDED(hr), "Failed to create descriptor heap, hr %#x.\n", hr);
16048 
16049     for (i = 0; i < ARRAY_SIZE(textures); ++i)
16050     {
16051         textures[i] = create_default_texture(context.device, 1, 1, DXGI_FORMAT_R32_FLOAT,
16052                 0, D3D12_RESOURCE_STATE_COPY_DEST);
16053         data.pData = &texture_data[i];
16054         data.RowPitch = sizeof(texture_data[i]);
16055         data.SlicePitch = data.RowPitch;
16056         upload_texture_data(textures[i], &data, 1, queue, command_list);
16057         reset_command_list(command_list, context.allocator);
16058         transition_resource_state(command_list, textures[i],
16059                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
16060     }
16061 
16062     for (i = 0; i < heap_desc.NumDescriptors; ++i)
16063     {
16064         ID3D12Device_CreateShaderResourceView(context.device, textures[2], NULL,
16065                 get_cpu_descriptor_handle(&context, heap, i));
16066     }
16067     for (i = 0; i < ARRAY_SIZE(textures); ++i)
16068     {
16069         ID3D12Device_CreateShaderResourceView(context.device, textures[i], NULL,
16070                 get_cpu_descriptor_handle(&context, cpu_heap, i));
16071     }
16072 
16073     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
16074 
16075     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
16076     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
16077     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
16078     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
16079     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
16080     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
16081 
16082     set_rect(&rect, 0, 0, 16, 32);
16083     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &rect);
16084     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
16085             get_gpu_descriptor_handle(&context, heap, 0));
16086     ID3D12Device_CopyDescriptorsSimple(context.device, 2,
16087             get_cpu_sampler_handle(&context, heap, 0),
16088             get_cpu_sampler_handle(&context, cpu_heap, 0),
16089             D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
16090     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
16091 
16092     set_rect(&rect, 16, 0, 32, 32);
16093     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &rect);
16094     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
16095             get_gpu_descriptor_handle(&context, heap, 2));
16096     ID3D12Device_CreateShaderResourceView(context.device, textures[1], NULL,
16097             get_cpu_descriptor_handle(&context, heap, 2));
16098     ID3D12Device_CreateShaderResourceView(context.device, textures[0], NULL,
16099             get_cpu_descriptor_handle(&context, heap, 3));
16100     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
16101 
16102     transition_resource_state(command_list, context.render_target,
16103             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
16104     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
16105     set_box(&box, 0, 0, 0, 16, 32, 1);
16106     check_readback_data_uint(&rb, &box, 0xff00407f, 1);
16107     set_box(&box, 16, 0, 0, 32, 32, 1);
16108     check_readback_data_uint(&rb, &box, 0xff007f40, 1);
16109     release_resource_readback(&rb);
16110 
16111     for (i = 0; i < ARRAY_SIZE(textures); ++i)
16112         ID3D12Resource_Release(textures[i]);
16113     ID3D12DescriptorHeap_Release(cpu_heap);
16114     ID3D12DescriptorHeap_Release(heap);
16115     destroy_test_context(&context);
16116 }
16117 
16118 /* This cannot be implemented reasonably in Vulkan. Vulkan doesn't allow
16119  * updating descriptor sets after the vkCmdBindDescriptorSets() command
16120  * is recorded.
16121  */
test_update_descriptor_heap_after_closing_command_list(void)16122 static void test_update_descriptor_heap_after_closing_command_list(void)
16123 {
16124     ID3D12Resource *red_texture, *green_texture;
16125     ID3D12GraphicsCommandList *command_list;
16126     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
16127     ID3D12DescriptorHeap *cpu_heap, *heap;
16128     D3D12_SUBRESOURCE_DATA texture_data;
16129     struct test_context_desc desc;
16130     struct resource_readback rb;
16131     struct test_context context;
16132     ID3D12CommandQueue *queue;
16133     unsigned int value;
16134     HRESULT hr;
16135 
16136     static const DWORD ps_code[] =
16137     {
16138 #if 0
16139         Texture2D t;
16140         SamplerState s;
16141 
16142         float4 main(float4 position : SV_POSITION) : SV_Target
16143         {
16144             float2 p;
16145 
16146             p.x = position.x / 32.0f;
16147             p.y = position.y / 32.0f;
16148             return t.Sample(s, p);
16149         }
16150 #endif
16151         0x43425844, 0x7a0c3929, 0x75ff3ca4, 0xccb318b2, 0xe6965b4c, 0x00000001, 0x00000140, 0x00000003,
16152         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
16153         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
16154         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
16155         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000a4, 0x00000050,
16156         0x00000029, 0x0100086a, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000,
16157         0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
16158         0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002,
16159         0x3d000000, 0x3d000000, 0x00000000, 0x00000000, 0x8b000045, 0x800000c2, 0x00155543, 0x001020f2,
16160         0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0100003e,
16161     };
16162     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
16163     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
16164     static const unsigned int red_data[] = {0xff0000ff};
16165     static const unsigned int green_data[] = {0xff00ff00};
16166 
16167     memset(&desc, 0, sizeof(desc));
16168     desc.no_root_signature = true;
16169     if (!init_test_context(&context, &desc))
16170         return;
16171     command_list = context.list;
16172     queue = context.queue;
16173 
16174     context.root_signature = create_texture_root_signature(context.device,
16175             D3D12_SHADER_VISIBILITY_PIXEL, 0, 0);
16176     context.pipeline_state = create_pipeline_state(context.device,
16177             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
16178 
16179     heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
16180     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
16181 
16182     cpu_heap = create_cpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
16183 
16184     red_texture = create_default_texture(context.device, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
16185             0, D3D12_RESOURCE_STATE_COPY_DEST);
16186     texture_data.pData = red_data;
16187     texture_data.RowPitch = sizeof(*red_data);
16188     texture_data.SlicePitch = texture_data.RowPitch;
16189     upload_texture_data(red_texture, &texture_data, 1, queue, command_list);
16190     reset_command_list(command_list, context.allocator);
16191     transition_resource_state(command_list, red_texture,
16192             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
16193 
16194     green_texture = create_default_texture(context.device, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
16195             0, D3D12_RESOURCE_STATE_COPY_DEST);
16196     texture_data.pData = green_data;
16197     upload_texture_data(green_texture, &texture_data, 1, queue, command_list);
16198     reset_command_list(command_list, context.allocator);
16199     transition_resource_state(command_list, green_texture,
16200             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
16201 
16202     ID3D12Device_CreateShaderResourceView(context.device, red_texture, NULL,
16203             get_cpu_descriptor_handle(&context, cpu_heap, 0));
16204     ID3D12Device_CopyDescriptorsSimple(context.device, 1,
16205             get_cpu_sampler_handle(&context, heap, 0),
16206             get_cpu_sampler_handle(&context, cpu_heap, 0),
16207             D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
16208 
16209     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
16210     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
16211     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
16212     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
16213     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
16214     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
16215             ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
16216     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
16217     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
16218     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
16219     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
16220 
16221     hr = ID3D12GraphicsCommandList_Close(command_list);
16222     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
16223 
16224     /* Update the descriptor heap used by the closed command list. */
16225     ID3D12Device_CreateShaderResourceView(context.device, green_texture, NULL, cpu_handle);
16226 
16227     exec_command_list(queue, command_list);
16228     wait_queue_idle(context.device, queue);
16229     reset_command_list(command_list, context.allocator);
16230 
16231     transition_resource_state(command_list, context.render_target,
16232             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
16233     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
16234     value = get_readback_uint(&rb, 0, 0, 0);
16235     todo ok(value == 0xff00ff00, "Got unexpected value %#x.\n", value);
16236     release_resource_readback(&rb);
16237 
16238     ID3D12DescriptorHeap_Release(cpu_heap);
16239     ID3D12DescriptorHeap_Release(heap);
16240     ID3D12Resource_Release(green_texture);
16241     ID3D12Resource_Release(red_texture);
16242     destroy_test_context(&context);
16243 }
16244 
test_update_compute_descriptor_tables(void)16245 static void test_update_compute_descriptor_tables(void)
16246 {
16247     struct cb_data
16248     {
16249         struct uvec4 srv_size[2];
16250         struct uvec4 uav_size[2];
16251     };
16252 
16253     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
16254     ID3D12PipelineState *buffer_pso, *texture_pso;
16255     D3D12_DESCRIPTOR_RANGE descriptor_ranges[4];
16256     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
16257     D3D12_CONSTANT_BUFFER_VIEW_DESC cbv_desc;
16258     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
16259     ID3D12GraphicsCommandList *command_list;
16260     D3D12_ROOT_PARAMETER root_parameters[5];
16261     D3D12_SUBRESOURCE_DATA subresource_data;
16262     ID3D12Resource *buffer_cb, *texture_cb;
16263     ID3D12DescriptorHeap *descriptor_heap;
16264     ID3D12Resource *output_buffers[2];
16265     ID3D12Resource *input_buffers[5];
16266     ID3D12Resource *textures[3];
16267     struct resource_readback rb;
16268     struct test_context context;
16269     ID3D12CommandQueue *queue;
16270     struct cb_data cb_data;
16271     ID3D12Device *device;
16272     unsigned int i;
16273     uint32_t data;
16274     HRESULT hr;
16275 
16276     static const DWORD cs_buffer_code[] =
16277     {
16278 #if 0
16279         uint offset;
16280 
16281         RWByteAddressBuffer u0 : register(u0);
16282 
16283         cbuffer cb0 : register(b0)
16284         {
16285             uint4 srv_size[2];
16286             uint4 uav_size[2];
16287         };
16288 
16289         Buffer<uint> t0 : register(t0);
16290         Buffer<uint> t1 : register(t1);
16291 
16292         RWBuffer<uint> u4 : register(u4);
16293         RWBuffer<uint> u7 : register(u7);
16294 
16295         [numthreads(1, 1, 1)]
16296         void main()
16297         {
16298             uint x, result, byte_offset = offset;
16299 
16300             for (x = 0, result = 0; x < srv_size[0].x; ++x)
16301                 result += t0.Load(x);
16302             u0.Store(byte_offset, result);
16303             byte_offset += 4;
16304 
16305             for (x = 0, result = 0; x < srv_size[1].x; ++x)
16306                 result += t1.Load(x);
16307             u0.Store(byte_offset, result);
16308             byte_offset += 4;
16309 
16310             for (x = 0, result = 0; x < uav_size[0].x; ++x)
16311                 result += u4[x];
16312             u0.Store(byte_offset, result);
16313             byte_offset += 4;
16314 
16315             for (x = 0, result = 0; x < uav_size[1].x; ++x)
16316                 result += u7[x];
16317             u0.Store(byte_offset, result);
16318         }
16319 #endif
16320         0x43425844, 0xb3d9f052, 0xcc3f0310, 0xd18f8515, 0xccabd8f6, 0x00000001, 0x00000404, 0x00000003,
16321         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
16322         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000003b0, 0x00050050, 0x000000ec, 0x0100086a,
16323         0x04000059, 0x00208e46, 0x00000001, 0x00000001, 0x04000059, 0x00208e46, 0x00000000, 0x00000004,
16324         0x04000858, 0x00107000, 0x00000000, 0x00004444, 0x04000858, 0x00107000, 0x00000001, 0x00004444,
16325         0x0300009d, 0x0011e000, 0x00000000, 0x0400089c, 0x0011e000, 0x00000004, 0x00004444, 0x0400089c,
16326         0x0011e000, 0x00000007, 0x00004444, 0x02000068, 0x00000002, 0x0400009b, 0x00000001, 0x00000001,
16327         0x00000001, 0x08000036, 0x00100032, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
16328         0x00000000, 0x01000030, 0x08000050, 0x00100012, 0x00000001, 0x0010001a, 0x00000000, 0x0020800a,
16329         0x00000000, 0x00000000, 0x03040003, 0x0010000a, 0x00000001, 0x8900002d, 0x80000042, 0x00111103,
16330         0x00100012, 0x00000001, 0x00100556, 0x00000000, 0x00107e46, 0x00000000, 0x0700001e, 0x00100012,
16331         0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0700001e, 0x00100022, 0x00000000,
16332         0x0010001a, 0x00000000, 0x00004001, 0x00000001, 0x01000016, 0x08000036, 0x00100032, 0x00000001,
16333         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01000030, 0x08000050, 0x00100042,
16334         0x00000001, 0x0010000a, 0x00000001, 0x0020800a, 0x00000000, 0x00000001, 0x03040003, 0x0010002a,
16335         0x00000001, 0x8900002d, 0x80000042, 0x00111103, 0x00100042, 0x00000001, 0x00100006, 0x00000001,
16336         0x00107c96, 0x00000001, 0x0700001e, 0x00100022, 0x00000001, 0x0010001a, 0x00000001, 0x0010002a,
16337         0x00000001, 0x0700001e, 0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x00004001, 0x00000001,
16338         0x01000016, 0x05000036, 0x00100022, 0x00000000, 0x0010001a, 0x00000001, 0x08000036, 0x00100032,
16339         0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01000030, 0x08000050,
16340         0x00100042, 0x00000001, 0x0010000a, 0x00000001, 0x0020800a, 0x00000000, 0x00000002, 0x03040003,
16341         0x0010002a, 0x00000001, 0x890000a3, 0x80000042, 0x00111103, 0x00100042, 0x00000001, 0x00100006,
16342         0x00000001, 0x0011ec96, 0x00000004, 0x0700001e, 0x00100022, 0x00000001, 0x0010001a, 0x00000001,
16343         0x0010002a, 0x00000001, 0x0700001e, 0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x00004001,
16344         0x00000001, 0x01000016, 0x05000036, 0x00100042, 0x00000000, 0x0010001a, 0x00000001, 0x08000036,
16345         0x00100032, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01000030,
16346         0x08000050, 0x00100042, 0x00000001, 0x0010000a, 0x00000001, 0x0020800a, 0x00000000, 0x00000003,
16347         0x03040003, 0x0010002a, 0x00000001, 0x890000a3, 0x80000042, 0x00111103, 0x00100042, 0x00000001,
16348         0x00100006, 0x00000001, 0x0011ec96, 0x00000007, 0x0700001e, 0x00100022, 0x00000001, 0x0010001a,
16349         0x00000001, 0x0010002a, 0x00000001, 0x0700001e, 0x00100012, 0x00000001, 0x0010000a, 0x00000001,
16350         0x00004001, 0x00000001, 0x01000016, 0x05000036, 0x00100082, 0x00000000, 0x0010001a, 0x00000001,
16351         0x080000a6, 0x0011e0f2, 0x00000000, 0x0020800a, 0x00000001, 0x00000000, 0x00100e46, 0x00000000,
16352         0x0100003e,
16353     };
16354     static const DWORD cs_texture_code[] =
16355     {
16356 #if 0
16357         uint offset;
16358 
16359         RWByteAddressBuffer u0 : register(u0);
16360 
16361         cbuffer cb0 : register(b0)
16362         {
16363             uint4 srv_size[2];
16364             uint4 uav_size[2];
16365         };
16366 
16367         Texture2D<uint> t0 : register(t0);
16368         Texture2D<uint> t1 : register(t1);
16369 
16370         RWBuffer<uint> u4 : register(u4);
16371         RWTexture2D<uint> u6 : register(u6);
16372 
16373         [numthreads(1, 1, 1)]
16374         void main()
16375         {
16376             uint x, y, result, byte_offset = offset;
16377 
16378             for (y = 0, result = 0; y < srv_size[0].y; ++y)
16379             {
16380                 for (x = 0; x < srv_size[0].x; ++x)
16381                     result += t0.Load(int3(x, y, 0));
16382             }
16383             u0.Store(byte_offset, result);
16384             byte_offset += 4;
16385 
16386             for (y = 0, result = 0; y < srv_size[1].y; ++y)
16387             {
16388                 for (x = 0; x < srv_size[1].x; ++x)
16389                     result += t1.Load(int3(x, y, 0));
16390             }
16391             u0.Store(byte_offset, result);
16392             byte_offset += 4;
16393 
16394             for (x = 0, result = 0; x < uav_size[0].x; ++x)
16395                 result += u4[x];
16396             u0.Store(byte_offset, result);
16397             byte_offset += 4;
16398 
16399             for (y = 0, result = 0; y < uav_size[1].y; ++y)
16400             {
16401                 for (x = 0; x < uav_size[1].x; ++x)
16402                     result += u6[uint2(x, y)];
16403             }
16404             u0.Store(byte_offset, result);
16405         }
16406 #endif
16407         0x43425844, 0x3f0f012e, 0xfb75f6aa, 0xb87ffe68, 0xf25f9ee6, 0x00000001, 0x00000650, 0x00000003,
16408         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
16409         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000005fc, 0x00050050, 0x0000017f, 0x0100086a,
16410         0x04000059, 0x00208e46, 0x00000001, 0x00000001, 0x04000059, 0x00208e46, 0x00000000, 0x00000004,
16411         0x04001858, 0x00107000, 0x00000000, 0x00004444, 0x04001858, 0x00107000, 0x00000001, 0x00004444,
16412         0x0300009d, 0x0011e000, 0x00000000, 0x0400089c, 0x0011e000, 0x00000004, 0x00004444, 0x0400189c,
16413         0x0011e000, 0x00000006, 0x00004444, 0x02000068, 0x00000004, 0x0400009b, 0x00000001, 0x00000001,
16414         0x00000001, 0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
16415         0x00000000, 0x05000036, 0x00100012, 0x00000001, 0x00004001, 0x00000000, 0x05000036, 0x00100012,
16416         0x00000002, 0x00004001, 0x00000000, 0x01000030, 0x08000050, 0x00100022, 0x00000001, 0x0010000a,
16417         0x00000001, 0x0020801a, 0x00000000, 0x00000000, 0x03040003, 0x0010001a, 0x00000001, 0x05000036,
16418         0x00100022, 0x00000000, 0x0010000a, 0x00000001, 0x05000036, 0x00100012, 0x00000003, 0x00004001,
16419         0x00000000, 0x05000036, 0x00100022, 0x00000003, 0x0010000a, 0x00000002, 0x01000030, 0x08000050,
16420         0x00100022, 0x00000001, 0x0010000a, 0x00000003, 0x0020800a, 0x00000000, 0x00000000, 0x03040003,
16421         0x0010001a, 0x00000001, 0x05000036, 0x00100012, 0x00000000, 0x0010000a, 0x00000003, 0x8900002d,
16422         0x800000c2, 0x00111103, 0x00100012, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000,
16423         0x0700001e, 0x00100022, 0x00000003, 0x0010001a, 0x00000003, 0x0010000a, 0x00000000, 0x0700001e,
16424         0x00100012, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x01000016, 0x05000036,
16425         0x00100012, 0x00000002, 0x0010001a, 0x00000003, 0x0700001e, 0x00100012, 0x00000001, 0x0010000a,
16426         0x00000001, 0x00004001, 0x00000001, 0x01000016, 0x08000036, 0x001000c2, 0x00000000, 0x00004002,
16427         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x05000036, 0x00100012, 0x00000001, 0x00004001,
16428         0x00000000, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0x00000000, 0x01000030, 0x08000050,
16429         0x00100022, 0x00000001, 0x0010000a, 0x00000001, 0x0020801a, 0x00000000, 0x00000001, 0x03040003,
16430         0x0010001a, 0x00000001, 0x05000036, 0x00100022, 0x00000000, 0x0010000a, 0x00000001, 0x05000036,
16431         0x00100012, 0x00000003, 0x00004001, 0x00000000, 0x05000036, 0x00100022, 0x00000003, 0x0010001a,
16432         0x00000002, 0x01000030, 0x08000050, 0x00100022, 0x00000001, 0x0010000a, 0x00000003, 0x0020800a,
16433         0x00000000, 0x00000001, 0x03040003, 0x0010001a, 0x00000001, 0x05000036, 0x00100012, 0x00000000,
16434         0x0010000a, 0x00000003, 0x8900002d, 0x800000c2, 0x00111103, 0x00100012, 0x00000000, 0x00100e46,
16435         0x00000000, 0x00107e46, 0x00000001, 0x0700001e, 0x00100022, 0x00000003, 0x0010001a, 0x00000003,
16436         0x0010000a, 0x00000000, 0x0700001e, 0x00100012, 0x00000003, 0x0010000a, 0x00000003, 0x00004001,
16437         0x00000001, 0x01000016, 0x05000036, 0x00100022, 0x00000002, 0x0010001a, 0x00000003, 0x0700001e,
16438         0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x00004001, 0x00000001, 0x01000016, 0x08000036,
16439         0x00100032, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01000030,
16440         0x08000050, 0x00100042, 0x00000000, 0x0010000a, 0x00000000, 0x0020800a, 0x00000000, 0x00000002,
16441         0x03040003, 0x0010002a, 0x00000000, 0x890000a3, 0x80000042, 0x00111103, 0x00100042, 0x00000000,
16442         0x00100006, 0x00000000, 0x0011ec96, 0x00000004, 0x0700001e, 0x00100022, 0x00000000, 0x0010001a,
16443         0x00000000, 0x0010002a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
16444         0x00004001, 0x00000001, 0x01000016, 0x05000036, 0x00100042, 0x00000002, 0x0010001a, 0x00000000,
16445         0x05000036, 0x00100012, 0x00000000, 0x00004001, 0x00000000, 0x05000036, 0x00100082, 0x00000002,
16446         0x00004001, 0x00000000, 0x01000030, 0x08000050, 0x00100022, 0x00000000, 0x0010000a, 0x00000000,
16447         0x0020801a, 0x00000000, 0x00000003, 0x03040003, 0x0010001a, 0x00000000, 0x05000036, 0x001000e2,
16448         0x00000001, 0x00100006, 0x00000000, 0x05000036, 0x00100012, 0x00000003, 0x00004001, 0x00000000,
16449         0x05000036, 0x00100022, 0x00000003, 0x0010003a, 0x00000002, 0x01000030, 0x08000050, 0x00100022,
16450         0x00000000, 0x0010000a, 0x00000003, 0x0020800a, 0x00000000, 0x00000003, 0x03040003, 0x0010001a,
16451         0x00000000, 0x05000036, 0x00100012, 0x00000001, 0x0010000a, 0x00000003, 0x890000a3, 0x800000c2,
16452         0x00111103, 0x00100022, 0x00000000, 0x00100e46, 0x00000001, 0x0011ee16, 0x00000006, 0x0700001e,
16453         0x00100022, 0x00000003, 0x0010001a, 0x00000003, 0x0010001a, 0x00000000, 0x0700001e, 0x00100012,
16454         0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x01000016, 0x05000036, 0x00100082,
16455         0x00000002, 0x0010001a, 0x00000003, 0x0700001e, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
16456         0x00004001, 0x00000001, 0x01000016, 0x080000a6, 0x0011e0f2, 0x00000000, 0x0020800a, 0x00000001,
16457         0x00000000, 0x00100e46, 0x00000002, 0x0100003e,
16458     };
16459     static const uint32_t buffer0_data[] = {1, 2, 3, 1};
16460     static const uint32_t buffer1_data[] = {10, 20, 30, 10};
16461     static const uint32_t buffer2_data[] = {100, 200, 300, 200};
16462     static const uint32_t buffer3_data[] = {1000, 2000, 2000, 2000};
16463     static const uint32_t buffer4_data[] = {0, 0, 0, 0};
16464     static const uint32_t texture0_data[4][4] =
16465     {
16466         {1, 0, 0, 0},
16467         {10000, 100, 1000, 10000},
16468         {0, 0, 0, 2},
16469         {0, 30000, 10000, 10},
16470     };
16471     static const uint32_t texture1_data[4][4] =
16472     {
16473         {6, 0, 0, 0},
16474         {600, 0, 1000, 60000},
16475         {0, 40, 0, 0},
16476         {0, 30000, 0, 0},
16477     };
16478     static const uint32_t texture2_data[4][4] =
16479     {
16480         {1, 1, 1, 1},
16481         {2, 2, 2, 2},
16482         {3, 3, 3, 3},
16483         {4, 4, 4, 4},
16484     };
16485     static const uint32_t expected_output0[] = {7, 70, 800, 7000, 70, 0, 800, 7000, 61113, 91646, 800, 40};
16486     static const uint32_t expected_output1[] = {61113, 91646, 800, 40, 7, 70, 800, 7000};
16487 
16488     if (!init_compute_test_context(&context))
16489         return;
16490     device = context.device;
16491     command_list = context.list;
16492     queue = context.queue;
16493 
16494     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
16495     root_parameters[0].Constants.ShaderRegister = 1;
16496     root_parameters[0].Constants.RegisterSpace = 0;
16497     root_parameters[0].Constants.Num32BitValues = 1;
16498     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
16499     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
16500     descriptor_ranges[0].NumDescriptors = 1;
16501     descriptor_ranges[0].BaseShaderRegister = 0;
16502     descriptor_ranges[0].RegisterSpace = 0;
16503     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
16504     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
16505     root_parameters[1].DescriptorTable.NumDescriptorRanges = 1;
16506     root_parameters[1].DescriptorTable.pDescriptorRanges = &descriptor_ranges[0];
16507     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
16508     descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
16509     descriptor_ranges[1].NumDescriptors = 2;
16510     descriptor_ranges[1].BaseShaderRegister = 0;
16511     descriptor_ranges[1].RegisterSpace = 0;
16512     descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 0;
16513     root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
16514     root_parameters[2].DescriptorTable.NumDescriptorRanges = 1;
16515     root_parameters[2].DescriptorTable.pDescriptorRanges = &descriptor_ranges[1];
16516     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
16517     descriptor_ranges[2].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
16518     descriptor_ranges[2].NumDescriptors = 4;
16519     descriptor_ranges[2].BaseShaderRegister = 4;
16520     descriptor_ranges[2].RegisterSpace = 0;
16521     descriptor_ranges[2].OffsetInDescriptorsFromTableStart = 0;
16522     root_parameters[3].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
16523     root_parameters[3].DescriptorTable.NumDescriptorRanges = 1;
16524     root_parameters[3].DescriptorTable.pDescriptorRanges = &descriptor_ranges[2];
16525     root_parameters[3].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
16526     descriptor_ranges[3].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
16527     descriptor_ranges[3].NumDescriptors = 1;
16528     descriptor_ranges[3].BaseShaderRegister = 0;
16529     descriptor_ranges[3].RegisterSpace = 0;
16530     descriptor_ranges[3].OffsetInDescriptorsFromTableStart = 0;
16531     root_parameters[4].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
16532     root_parameters[4].DescriptorTable.NumDescriptorRanges = 1;
16533     root_parameters[4].DescriptorTable.pDescriptorRanges = &descriptor_ranges[3];
16534     root_parameters[4].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
16535     root_signature_desc.NumParameters = 5;
16536     root_signature_desc.pParameters = root_parameters;
16537     root_signature_desc.NumStaticSamplers = 0;
16538     root_signature_desc.pStaticSamplers = NULL;
16539     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
16540     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
16541     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
16542 
16543     buffer_pso = create_compute_pipeline_state(device, context.root_signature,
16544             shader_bytecode(cs_buffer_code, sizeof(cs_buffer_code)));
16545     texture_pso = create_compute_pipeline_state(device, context.root_signature,
16546             shader_bytecode(cs_texture_code, sizeof(cs_texture_code)));
16547 
16548     for (i = 0; i < ARRAY_SIZE(output_buffers); ++i)
16549     {
16550         output_buffers[i] = create_default_buffer(device, 1024,
16551                 D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
16552     }
16553 
16554     input_buffers[0] = create_default_buffer(device, sizeof(buffer0_data),
16555             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
16556     upload_buffer_data(input_buffers[0], 0, sizeof(buffer0_data), buffer0_data, queue, command_list);
16557     reset_command_list(command_list, context.allocator);
16558     transition_resource_state(command_list, input_buffers[0],
16559             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
16560 
16561     input_buffers[1] = create_default_buffer(device, sizeof(buffer1_data),
16562             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
16563     upload_buffer_data(input_buffers[1], 0, sizeof(buffer1_data), buffer1_data, queue, command_list);
16564     reset_command_list(command_list, context.allocator);
16565     transition_resource_state(command_list, input_buffers[1],
16566             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
16567 
16568     input_buffers[2] = create_default_buffer(device, sizeof(buffer2_data),
16569             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
16570     upload_buffer_data(input_buffers[2], 0, sizeof(buffer2_data), buffer2_data, queue, command_list);
16571     reset_command_list(command_list, context.allocator);
16572     transition_resource_state(command_list, input_buffers[2],
16573             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
16574 
16575     input_buffers[3] = create_default_buffer(device, sizeof(buffer3_data),
16576             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
16577     upload_buffer_data(input_buffers[3], 0, sizeof(buffer3_data), buffer3_data, queue, command_list);
16578     reset_command_list(command_list, context.allocator);
16579     transition_resource_state(command_list, input_buffers[3],
16580             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
16581 
16582     input_buffers[4] = create_default_buffer(device, sizeof(buffer4_data),
16583             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
16584     upload_buffer_data(input_buffers[4], 0, sizeof(buffer4_data), buffer4_data, queue, command_list);
16585     reset_command_list(command_list, context.allocator);
16586     transition_resource_state(command_list, input_buffers[4],
16587             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
16588 
16589     textures[0] = create_default_texture(context.device,
16590             4, 4, DXGI_FORMAT_R32_UINT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
16591     subresource_data.pData = texture0_data;
16592     subresource_data.RowPitch = sizeof(*texture0_data);
16593     subresource_data.SlicePitch = subresource_data.RowPitch;
16594     upload_texture_data(textures[0], &subresource_data, 1, queue, command_list);
16595     reset_command_list(command_list, context.allocator);
16596     transition_resource_state(command_list, textures[0],
16597             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
16598 
16599     textures[1] = create_default_texture(context.device,
16600             4, 4, DXGI_FORMAT_R32_UINT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
16601     subresource_data.pData = texture1_data;
16602     subresource_data.RowPitch = sizeof(*texture1_data);
16603     subresource_data.SlicePitch = subresource_data.RowPitch;
16604     upload_texture_data(textures[1], &subresource_data, 1, queue, command_list);
16605     reset_command_list(command_list, context.allocator);
16606     transition_resource_state(command_list, textures[1],
16607             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
16608 
16609     textures[2] = create_default_texture(context.device, 4, 4, DXGI_FORMAT_R32_UINT,
16610             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
16611     subresource_data.pData = texture2_data;
16612     subresource_data.RowPitch = sizeof(*texture2_data);
16613     subresource_data.SlicePitch = subresource_data.RowPitch;
16614     upload_texture_data(textures[2], &subresource_data, 1, queue, command_list);
16615     reset_command_list(command_list, context.allocator);
16616     transition_resource_state(command_list, textures[2],
16617             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
16618 
16619     memset(&cb_data, 0, sizeof(cb_data));
16620     cb_data.srv_size[0].x = ARRAY_SIZE(buffer0_data);
16621     cb_data.srv_size[1].x = ARRAY_SIZE(buffer1_data);
16622     cb_data.uav_size[0].x = ARRAY_SIZE(buffer2_data);
16623     cb_data.uav_size[1].x = ARRAY_SIZE(buffer3_data);
16624     buffer_cb = create_upload_buffer(device, sizeof(cb_data), &cb_data);
16625 
16626     memset(&cb_data, 0, sizeof(cb_data));
16627     cb_data.srv_size[0].x = 4;
16628     cb_data.srv_size[0].y = 4;
16629     cb_data.srv_size[1].x = 4;
16630     cb_data.srv_size[1].y = 4;
16631     cb_data.uav_size[0].x = ARRAY_SIZE(buffer2_data);
16632     cb_data.uav_size[1].x = 4;
16633     cb_data.uav_size[1].y = 4;
16634     texture_cb = create_upload_buffer(device, sizeof(cb_data), &cb_data);
16635 
16636     descriptor_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 30);
16637 
16638     memset(&srv_desc, 0, sizeof(srv_desc));
16639     srv_desc.Format = DXGI_FORMAT_R32_UINT;
16640     srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
16641     srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
16642     srv_desc.Buffer.FirstElement = 0;
16643     srv_desc.Buffer.NumElements = ARRAY_SIZE(buffer0_data);
16644     ID3D12Device_CreateShaderResourceView(device, input_buffers[0], &srv_desc,
16645             get_cpu_descriptor_handle(&context, descriptor_heap, 0));
16646     srv_desc.Buffer.NumElements = ARRAY_SIZE(buffer1_data);
16647     ID3D12Device_CreateShaderResourceView(device, input_buffers[1], &srv_desc,
16648             get_cpu_descriptor_handle(&context, descriptor_heap, 1));
16649 
16650     ID3D12Device_CreateShaderResourceView(device, input_buffers[1], &srv_desc,
16651             get_cpu_descriptor_handle(&context, descriptor_heap, 6));
16652     srv_desc.Buffer.NumElements = ARRAY_SIZE(buffer4_data);
16653     ID3D12Device_CreateShaderResourceView(device, input_buffers[4], &srv_desc,
16654             get_cpu_descriptor_handle(&context, descriptor_heap, 7));
16655 
16656     memset(&uav_desc, 0, sizeof(uav_desc));
16657     uav_desc.Format = DXGI_FORMAT_R32_UINT;
16658     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
16659     uav_desc.Buffer.FirstElement = 0;
16660     uav_desc.Buffer.NumElements = ARRAY_SIZE(buffer2_data);
16661     ID3D12Device_CreateUnorderedAccessView(device, input_buffers[2], NULL, &uav_desc,
16662             get_cpu_descriptor_handle(&context, descriptor_heap, 2));
16663     ID3D12Device_CreateUnorderedAccessView(device, input_buffers[2], NULL, &uav_desc,
16664             get_cpu_descriptor_handle(&context, descriptor_heap, 12));
16665     uav_desc.Buffer.NumElements = ARRAY_SIZE(buffer3_data);
16666     ID3D12Device_CreateUnorderedAccessView(device, input_buffers[3], NULL, &uav_desc,
16667             get_cpu_descriptor_handle(&context, descriptor_heap, 5));
16668 
16669     ID3D12Device_CreateShaderResourceView(device, textures[0], NULL,
16670             get_cpu_descriptor_handle(&context, descriptor_heap, 10));
16671     ID3D12Device_CreateShaderResourceView(device, textures[1], NULL,
16672             get_cpu_descriptor_handle(&context, descriptor_heap, 11));
16673 
16674     ID3D12Device_CreateUnorderedAccessView(device, textures[2], NULL, NULL,
16675             get_cpu_descriptor_handle(&context, descriptor_heap, 14));
16676 
16677     cbv_desc.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(buffer_cb);
16678     cbv_desc.SizeInBytes = align(sizeof(cb_data), D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT);
16679     ID3D12Device_CreateConstantBufferView(context.device, &cbv_desc,
16680             get_cpu_descriptor_handle(&context, descriptor_heap, 8));
16681 
16682     cbv_desc.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(texture_cb);
16683     cbv_desc.SizeInBytes = align(sizeof(cb_data), D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT);
16684     ID3D12Device_CreateConstantBufferView(context.device, &cbv_desc,
16685             get_cpu_descriptor_handle(&context, descriptor_heap, 9));
16686 
16687     memset(&uav_desc, 0, sizeof(uav_desc));
16688     uav_desc.Format = DXGI_FORMAT_R32_TYPELESS;
16689     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
16690     uav_desc.Buffer.FirstElement = 0;
16691     uav_desc.Buffer.NumElements = 256;
16692     uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
16693     ID3D12Device_CreateUnorderedAccessView(device, output_buffers[0], NULL, &uav_desc,
16694             get_cpu_descriptor_handle(&context, descriptor_heap, 20));
16695     ID3D12Device_CreateUnorderedAccessView(device, output_buffers[1], NULL, &uav_desc,
16696             get_cpu_descriptor_handle(&context, descriptor_heap, 21));
16697 
16698     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
16699     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
16700 
16701     ID3D12GraphicsCommandList_SetPipelineState(command_list, buffer_pso);
16702 
16703     ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(command_list, 0, 0 /* offset */, 0);
16704     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
16705             1, get_gpu_descriptor_handle(&context, descriptor_heap, 20)); /* u0 */
16706     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
16707             2, get_gpu_descriptor_handle(&context, descriptor_heap, 0)); /* t1-t2 */
16708     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
16709             3, get_gpu_descriptor_handle(&context, descriptor_heap, 2)); /* u4-u7 */
16710     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
16711             4, get_gpu_descriptor_handle(&context, descriptor_heap, 8)); /* b0 */
16712     ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
16713 
16714     ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(command_list, 0, 16 /* offset */, 0);
16715     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
16716             2, get_gpu_descriptor_handle(&context, descriptor_heap, 6));  /* t1-t2 */
16717     ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
16718 
16719     ID3D12GraphicsCommandList_SetPipelineState(command_list, texture_pso);
16720 
16721     transition_resource_state(command_list, input_buffers[4],
16722             D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
16723     ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(command_list, 0, 32 /* offset */, 0);
16724     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
16725             2, get_gpu_descriptor_handle(&context, descriptor_heap, 10)); /* t1-t2 */
16726     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
16727             3, get_gpu_descriptor_handle(&context, descriptor_heap, 12)); /* u4-u7 */
16728     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
16729             4, get_gpu_descriptor_handle(&context, descriptor_heap, 9)); /* b0 */
16730     ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
16731 
16732     ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(command_list, 0, 0 /* offset */, 0);
16733     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
16734             1, get_gpu_descriptor_handle(&context, descriptor_heap, 21)); /* u0 */
16735     ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
16736 
16737     ID3D12GraphicsCommandList_SetPipelineState(command_list, buffer_pso);
16738 
16739     ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(command_list, 0, 16 /* offset */, 0);
16740     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
16741             2, get_gpu_descriptor_handle(&context, descriptor_heap, 0)); /* t1-t2 */
16742     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
16743             3, get_gpu_descriptor_handle(&context, descriptor_heap, 2)); /* u4-u7 */
16744     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
16745             4, get_gpu_descriptor_handle(&context, descriptor_heap, 8)); /* b0 */
16746     ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
16747 
16748     transition_sub_resource_state(command_list, output_buffers[0], 0,
16749             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
16750     get_buffer_readback_with_command_list(output_buffers[0], DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
16751     for (i = 0; i < ARRAY_SIZE(expected_output0); ++i)
16752     {
16753         data = get_readback_uint(&rb, i, 0, 0);
16754         ok(data == expected_output0[i], "Got %#x, expected %#x at %u.\n", data, expected_output0[i], i);
16755     }
16756     release_resource_readback(&rb);
16757 
16758     reset_command_list(command_list, context.allocator);
16759     transition_sub_resource_state(command_list, output_buffers[1], 0,
16760             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
16761     get_buffer_readback_with_command_list(output_buffers[1], DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
16762     for (i = 0; i < ARRAY_SIZE(expected_output1); ++i)
16763     {
16764         data = get_readback_uint(&rb, i, 0, 0);
16765         ok(data == expected_output1[i], "Got %#x, expected %#x at %u.\n", data, expected_output1[i], i);
16766     }
16767     release_resource_readback(&rb);
16768 
16769     ID3D12Resource_Release(buffer_cb);
16770     ID3D12Resource_Release(texture_cb);
16771     for (i = 0; i < ARRAY_SIZE(input_buffers); ++i)
16772         ID3D12Resource_Release(input_buffers[i]);
16773     for (i = 0; i < ARRAY_SIZE(textures); ++i)
16774         ID3D12Resource_Release(textures[i]);
16775     for (i = 0; i < ARRAY_SIZE(output_buffers); ++i)
16776         ID3D12Resource_Release(output_buffers[i]);
16777     ID3D12PipelineState_Release(buffer_pso);
16778     ID3D12PipelineState_Release(texture_pso);
16779     ID3D12DescriptorHeap_Release(descriptor_heap);
16780     destroy_test_context(&context);
16781 }
16782 
test_update_descriptor_tables_after_root_signature_change(void)16783 static void test_update_descriptor_tables_after_root_signature_change(void)
16784 {
16785     ID3D12RootSignature *root_signature, *root_signature2;
16786     ID3D12PipelineState *pipeline_state, *pipeline_state2;
16787     ID3D12DescriptorHeap *heap, *sampler_heap, *heaps[2];
16788     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
16789     D3D12_DESCRIPTOR_RANGE descriptor_range[4];
16790     D3D12_ROOT_PARAMETER root_parameters[3];
16791     ID3D12GraphicsCommandList *command_list;
16792     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
16793     unsigned int i, descriptor_size;
16794     D3D12_SAMPLER_DESC sampler_desc;
16795     struct test_context_desc desc;
16796     ID3D12Resource *textures[2];
16797     D3D12_SUBRESOURCE_DATA data;
16798     struct test_context context;
16799     ID3D12CommandQueue *queue;
16800     HRESULT hr;
16801 
16802     static const DWORD ps_code[] =
16803     {
16804 #if 0
16805         Texture2D t;
16806         SamplerState s;
16807 
16808         float4 main(float4 position : SV_POSITION) : SV_Target
16809         {
16810             float2 p;
16811 
16812             p.x = position.x / 32.0f;
16813             p.y = position.y / 32.0f;
16814             return t.Sample(s, p);
16815         }
16816 #endif
16817         0x43425844, 0x7a0c3929, 0x75ff3ca4, 0xccb318b2, 0xe6965b4c, 0x00000001, 0x00000140, 0x00000003,
16818         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
16819         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
16820         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
16821         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000a4, 0x00000050,
16822         0x00000029, 0x0100086a, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000,
16823         0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
16824         0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002,
16825         0x3d000000, 0x3d000000, 0x00000000, 0x00000000, 0x8b000045, 0x800000c2, 0x00155543, 0x001020f2,
16826         0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0100003e,
16827     };
16828     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
16829     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
16830     static const unsigned int texture_data[] = {0xff00ff00, 0xff0000ff};
16831 
16832     memset(&desc, 0, sizeof(desc));
16833     desc.no_root_signature = true;
16834     if (!init_test_context(&context, &desc))
16835         return;
16836     command_list = context.list;
16837     queue = context.queue;
16838 
16839     descriptor_range[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
16840     descriptor_range[0].NumDescriptors = 2;
16841     descriptor_range[0].BaseShaderRegister = 0;
16842     descriptor_range[0].RegisterSpace = 0;
16843     descriptor_range[0].OffsetInDescriptorsFromTableStart = 0;
16844     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
16845     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
16846     root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_range[0];
16847     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
16848 
16849     descriptor_range[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
16850     descriptor_range[1].NumDescriptors = 1;
16851     descriptor_range[1].BaseShaderRegister = 0;
16852     descriptor_range[1].RegisterSpace = 0;
16853     descriptor_range[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
16854     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
16855     root_parameters[1].DescriptorTable.NumDescriptorRanges = 1;
16856     root_parameters[1].DescriptorTable.pDescriptorRanges = &descriptor_range[1];
16857     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
16858 
16859     descriptor_range[2].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
16860     descriptor_range[2].NumDescriptors = 2;
16861     descriptor_range[2].BaseShaderRegister = 2;
16862     descriptor_range[2].RegisterSpace = 0;
16863     descriptor_range[2].OffsetInDescriptorsFromTableStart = 0;
16864     descriptor_range[3].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
16865     descriptor_range[3].NumDescriptors = 1;
16866     descriptor_range[3].BaseShaderRegister = 0;
16867     descriptor_range[3].RegisterSpace = 0;
16868     descriptor_range[3].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
16869     root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
16870     root_parameters[2].DescriptorTable.NumDescriptorRanges = 2;
16871     root_parameters[2].DescriptorTable.pDescriptorRanges = &descriptor_range[2];
16872     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
16873 
16874     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
16875     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
16876     root_signature_desc.pParameters = root_parameters;
16877     hr = create_root_signature(context.device, &root_signature_desc, &root_signature);
16878     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
16879     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters) - 1;
16880     hr = create_root_signature(context.device, &root_signature_desc, &root_signature2);
16881     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
16882 
16883     pipeline_state = create_pipeline_state(context.device,
16884             root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
16885     pipeline_state2 = create_pipeline_state(context.device,
16886             root_signature2, context.render_target_desc.Format, NULL, &ps, NULL);
16887 
16888     heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 6);
16889     sampler_heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 1);
16890 
16891     memset(&sampler_desc, 0, sizeof(sampler_desc));
16892     sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
16893     sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
16894     sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
16895     sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
16896     ID3D12Device_CreateSampler(context.device, &sampler_desc, get_cpu_descriptor_handle(&context, sampler_heap, 0));
16897 
16898     descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(context.device,
16899             D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
16900 
16901     for (i = 0; i < ARRAY_SIZE(textures); ++i)
16902     {
16903         textures[i] = create_default_texture(context.device,
16904                 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D12_RESOURCE_STATE_COPY_DEST);
16905         data.pData = &texture_data[i];
16906         data.RowPitch = sizeof(texture_data[i]);
16907         data.SlicePitch = data.RowPitch;
16908         upload_texture_data(textures[i], &data, 1, queue, command_list);
16909         reset_command_list(command_list, context.allocator);
16910     }
16911 
16912     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
16913     for (i = 0; i < ARRAY_SIZE(textures); ++i)
16914     {
16915         transition_resource_state(command_list, textures[i],
16916                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
16917         ID3D12Device_CreateShaderResourceView(context.device, textures[i], NULL, cpu_handle);
16918         cpu_handle.ptr += descriptor_size;
16919     }
16920     for (; i < 6; ++i)
16921     {
16922         ID3D12Device_CreateShaderResourceView(context.device, textures[1], NULL, cpu_handle);
16923         cpu_handle.ptr += descriptor_size;
16924     }
16925 
16926     heaps[0] = heap; heaps[1] = sampler_heap;
16927     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, ARRAY_SIZE(heaps), heaps);
16928 
16929     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
16930 
16931     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
16932     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, root_signature);
16933     ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
16934 
16935     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
16936     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
16937     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
16938 
16939     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
16940             get_gpu_descriptor_handle(&context, heap, 0));
16941     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 1,
16942             ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(sampler_heap));
16943     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 2,
16944             get_gpu_descriptor_handle(&context, heap, 2));
16945 
16946     ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state2);
16947     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, root_signature2);
16948 
16949     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
16950             get_gpu_descriptor_handle(&context, heap, 0));
16951     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 1,
16952             ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(sampler_heap));
16953 
16954     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
16955 
16956     transition_resource_state(command_list, context.render_target,
16957             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
16958     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
16959 
16960     reset_command_list(command_list, context.allocator);
16961     transition_resource_state(command_list, context.render_target,
16962             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
16963 
16964     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, ARRAY_SIZE(heaps), heaps);
16965 
16966     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
16967 
16968     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
16969     ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state2);
16970     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, root_signature2);
16971 
16972     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
16973     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
16974     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
16975 
16976     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
16977             get_gpu_descriptor_handle(&context, heap, 0));
16978     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 1,
16979             ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(sampler_heap));
16980 
16981     ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
16982     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, root_signature);
16983 
16984     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
16985 
16986     transition_resource_state(command_list, context.render_target,
16987             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
16988     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
16989 
16990     ID3D12PipelineState_Release(pipeline_state);
16991     ID3D12PipelineState_Release(pipeline_state2);
16992     ID3D12RootSignature_Release(root_signature);
16993     ID3D12RootSignature_Release(root_signature2);
16994     for (i = 0; i < ARRAY_SIZE(textures); ++i)
16995         ID3D12Resource_Release(textures[i]);
16996     ID3D12DescriptorHeap_Release(heap);
16997     ID3D12DescriptorHeap_Release(sampler_heap);
16998     destroy_test_context(&context);
16999 }
17000 
test_copy_descriptors(void)17001 static void test_copy_descriptors(void)
17002 {
17003     struct data
17004     {
17005         unsigned int u[3];
17006         float f;
17007     };
17008 
17009     ID3D12DescriptorHeap *cpu_heap, *cpu_sampler_heap, *cpu_sampler_heap2;
17010     D3D12_CPU_DESCRIPTOR_HANDLE dst_handles[4], src_handles[4];
17011     ID3D12DescriptorHeap *heap, *sampler_heap, *heaps[2];
17012     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
17013     D3D12_DESCRIPTOR_RANGE descriptor_ranges[5];
17014     UINT dst_range_sizes[4], src_range_sizes[4];
17015     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
17016     D3D12_CONSTANT_BUFFER_VIEW_DESC cbv_desc;
17017     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
17018     ID3D12GraphicsCommandList *command_list;
17019     D3D12_ROOT_PARAMETER root_parameters[4];
17020     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
17021     ID3D12Resource *t[7], *u[3], *cb;
17022     struct depth_stencil_resource ds;
17023     D3D12_SAMPLER_DESC sampler_desc;
17024     struct test_context_desc desc;
17025     unsigned int descriptor_size;
17026     D3D12_SUBRESOURCE_DATA data;
17027     struct resource_readback rb;
17028     struct test_context context;
17029     ID3D12CommandQueue *queue;
17030     unsigned int sampler_size;
17031     ID3D12Device *device;
17032     unsigned int *result;
17033     unsigned int i;
17034     HRESULT hr;
17035 
17036     static const DWORD cs_code[] =
17037     {
17038 #if 0
17039         struct data
17040         {
17041             uint3 u;
17042             float f;
17043         };
17044 
17045         cbuffer cb0
17046         {
17047             float f;
17048         };
17049 
17050         cbuffer cb1
17051         {
17052             uint u;
17053         };
17054 
17055         cbuffer cb2
17056         {
17057             int i;
17058         };
17059 
17060         SamplerState s0;
17061         SamplerState s1;
17062         SamplerState s2;
17063         SamplerComparisonState s3;
17064 
17065         Texture2D t0;
17066         Texture2D<uint> t1;
17067         Texture2D<int> t2;
17068         Buffer<float> t3;
17069         StructuredBuffer<float> t4;
17070         ByteAddressBuffer t5;
17071         Texture2D t6;
17072 
17073         RWByteAddressBuffer u0;
17074         RWStructuredBuffer<data> u1;
17075 
17076         RWByteAddressBuffer u2;
17077 
17078         [numthreads(1, 1, 1)]
17079         void main()
17080         {
17081             u2.Store(0 * 4, f);
17082             u2.Store(1 * 4, u);
17083             u2.Store(2 * 4, i);
17084             u2.Store(3 * 4, 0);
17085 
17086             u2.Store4( 4 * 4, t0.SampleLevel(s0, (float2)0, 0));
17087             u2.Store4( 8 * 4, t0.SampleLevel(s1, (float2)0, 0));
17088             u2.Store4(12 * 4, t0.SampleLevel(s2, (float2)0, 0));
17089 
17090             u2.Store(16 * 4, t1.Load((int3)0));
17091             u2.Store(17 * 4, t2.Load((int3)0));
17092             u2.Store(18 * 4, t3.Load(0));
17093             u2.Store(19 * 4, t4[0]);
17094 
17095             u2.Store4(20 * 4, t5.Load4(0));
17096 
17097             u2.Store4(24 * 4, t6.SampleCmpLevelZero(s3, (float2)0, 0.6f));
17098             u2.Store4(28 * 4, t6.SampleCmpLevelZero(s3, (float2)0, 0.4f));
17099 
17100             u2.Store2(32 * 4, u0.Load2(0));
17101             u2.Store2(34 * 4, u0.Load2(8));
17102 
17103             u2.Store3(36 * 4, u1[0].u);
17104             u2.Store4(39 * 4, u1[0].f);
17105 
17106             u2.Store(43 * 4, 0xdeadbeef);
17107         }
17108 #endif
17109         0x43425844, 0x52d2c2d3, 0xaf60e190, 0xb897944f, 0x4a6a6653, 0x00000001, 0x00000650, 0x00000003,
17110         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
17111         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000005fc, 0x00050050, 0x0000017f, 0x0100086a,
17112         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000059, 0x00208e46, 0x00000001, 0x00000001,
17113         0x04000059, 0x00208e46, 0x00000002, 0x00000001, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a,
17114         0x00106000, 0x00000001, 0x0300005a, 0x00106000, 0x00000002, 0x0300085a, 0x00106000, 0x00000003,
17115         0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00004444,
17116         0x04001858, 0x00107000, 0x00000002, 0x00003333, 0x04000858, 0x00107000, 0x00000003, 0x00005555,
17117         0x040000a2, 0x00107000, 0x00000004, 0x00000004, 0x030000a1, 0x00107000, 0x00000005, 0x04001858,
17118         0x00107000, 0x00000006, 0x00005555, 0x0300009d, 0x0011e000, 0x00000000, 0x0400009e, 0x0011e000,
17119         0x00000001, 0x00000010, 0x0300009d, 0x0011e000, 0x00000002, 0x02000068, 0x00000002, 0x0400009b,
17120         0x00000001, 0x00000001, 0x00000001, 0x0600001c, 0x00100012, 0x00000000, 0x0020800a, 0x00000000,
17121         0x00000000, 0x06000036, 0x00100022, 0x00000000, 0x0020800a, 0x00000001, 0x00000000, 0x06000036,
17122         0x00100042, 0x00000000, 0x0020800a, 0x00000002, 0x00000000, 0x05000036, 0x00100082, 0x00000000,
17123         0x00004001, 0x00000000, 0x070000a6, 0x0011e0f2, 0x00000002, 0x00004001, 0x00000000, 0x00100e46,
17124         0x00000000, 0x90000048, 0x800000c2, 0x00155543, 0x001000f2, 0x00000000, 0x00004002, 0x00000000,
17125         0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x00004001,
17126         0x00000000, 0x0500001c, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x070000a6, 0x0011e0f2,
17127         0x00000002, 0x00004001, 0x00000010, 0x00100e46, 0x00000000, 0x90000048, 0x800000c2, 0x00155543,
17128         0x001000f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46,
17129         0x00000000, 0x00106000, 0x00000001, 0x00004001, 0x00000000, 0x0500001c, 0x001000f2, 0x00000000,
17130         0x00100e46, 0x00000000, 0x070000a6, 0x0011e0f2, 0x00000002, 0x00004001, 0x00000020, 0x00100e46,
17131         0x00000000, 0x90000048, 0x800000c2, 0x00155543, 0x001000f2, 0x00000000, 0x00004002, 0x00000000,
17132         0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000002, 0x00004001,
17133         0x00000000, 0x0500001c, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x070000a6, 0x0011e0f2,
17134         0x00000002, 0x00004001, 0x00000030, 0x00100e46, 0x00000000, 0x8c00002d, 0x80000042, 0x00155543,
17135         0x00100012, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46,
17136         0x00000003, 0x0500001c, 0x00100042, 0x00000000, 0x0010000a, 0x00000000, 0x8b0000a7, 0x80002302,
17137         0x00199983, 0x00100012, 0x00000001, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x00107006,
17138         0x00000004, 0x0500001c, 0x00100082, 0x00000000, 0x0010000a, 0x00000001, 0x8c00002d, 0x800000c2,
17139         0x00111103, 0x00100012, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
17140         0x00107e46, 0x00000001, 0x8c00002d, 0x800000c2, 0x000cccc3, 0x00100022, 0x00000000, 0x00004002,
17141         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e16, 0x00000002, 0x070000a6, 0x0011e0f2,
17142         0x00000002, 0x00004001, 0x00000040, 0x00100e46, 0x00000000, 0x890000a5, 0x800002c2, 0x00199983,
17143         0x001000f2, 0x00000000, 0x00004001, 0x00000000, 0x00107e46, 0x00000005, 0x070000a6, 0x0011e0f2,
17144         0x00000002, 0x00004001, 0x00000050, 0x00100e46, 0x00000000, 0x90000047, 0x800000c2, 0x00155543,
17145         0x00100012, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107006,
17146         0x00000006, 0x00106000, 0x00000003, 0x00004001, 0x3f19999a, 0x0500001c, 0x00100012, 0x00000000,
17147         0x0010000a, 0x00000000, 0x070000a6, 0x0011e0f2, 0x00000002, 0x00004001, 0x00000060, 0x00100006,
17148         0x00000000, 0x90000047, 0x800000c2, 0x00155543, 0x00100012, 0x00000000, 0x00004002, 0x00000000,
17149         0x00000000, 0x00000000, 0x00000000, 0x00107006, 0x00000006, 0x00106000, 0x00000003, 0x00004001,
17150         0x3ecccccd, 0x0500001c, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x070000a6, 0x0011e0f2,
17151         0x00000002, 0x00004001, 0x00000070, 0x00100006, 0x00000000, 0x890000a5, 0x800002c2, 0x00199983,
17152         0x00100032, 0x00000000, 0x00004001, 0x00000000, 0x0011e046, 0x00000000, 0x890000a5, 0x800002c2,
17153         0x00199983, 0x001000c2, 0x00000000, 0x00004001, 0x00000008, 0x0011e406, 0x00000000, 0x070000a6,
17154         0x0011e0f2, 0x00000002, 0x00004001, 0x00000080, 0x00100e46, 0x00000000, 0x8b0000a7, 0x80008302,
17155         0x00199983, 0x001000f2, 0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x0011ee46,
17156         0x00000001, 0x070000a6, 0x0011e072, 0x00000002, 0x00004001, 0x00000090, 0x00100246, 0x00000000,
17157         0x0500001c, 0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x070000a6, 0x0011e0f2, 0x00000002,
17158         0x00004001, 0x0000009c, 0x00100006, 0x00000000, 0x070000a6, 0x0011e012, 0x00000002, 0x00004001,
17159         0x000000ac, 0x00004001, 0xdeadbeef, 0x0100003e,
17160     };
17161     static const float cb0_data = 10.0f;
17162     static const UINT cb1_data = 11;
17163     static const INT cb2_data = -1;
17164     static const struct vec4 t0_data = {1.0f, 2.0f, 3.0f, 4.0f};
17165     static const UINT t1_data = 111;
17166     static const INT t2_data = 222;
17167     static const float t3_data = 333.3f;
17168     static const float t4_data = 44.44f;
17169     static const struct uvec4 t5_data = {50, 51, 52, 53};
17170     static const struct uvec4 u0_data = {10, 20, 30, 40};
17171     static const struct data u1_data = {{5, 6, 7}, 10.0f};
17172 
17173     memset(&desc, 0, sizeof(desc));
17174     desc.no_render_target = true;
17175     if (!init_test_context(&context, &desc))
17176         return;
17177     device = context.device;
17178     command_list = context.list;
17179     queue = context.queue;
17180 
17181     descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(device,
17182             D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17183     sampler_size = ID3D12Device_GetDescriptorHandleIncrementSize(device,
17184             D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
17185 
17186     cpu_sampler_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 2);
17187     cpu_sampler_heap2 = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 2);
17188     sampler_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 4);
17189 
17190     cpu_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 30);
17191     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 30);
17192 
17193     /* create samplers */
17194     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cpu_sampler_heap);
17195     memset(&sampler_desc, 0, sizeof(sampler_desc));
17196     sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
17197     sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
17198     sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
17199     sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
17200     ID3D12Device_CreateSampler(context.device, &sampler_desc, cpu_handle);
17201     sampler_desc.Filter = D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT;
17202     sampler_desc.ComparisonFunc = D3D12_COMPARISON_FUNC_GREATER;
17203     cpu_handle.ptr += sampler_size;
17204     ID3D12Device_CreateSampler(context.device, &sampler_desc, cpu_handle);
17205 
17206     /* create CBVs */
17207     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cpu_heap);
17208     cb = create_upload_buffer(context.device,
17209             3 * D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, NULL);
17210     update_buffer_data(cb, 0, sizeof(cb0_data), &cb0_data);
17211     update_buffer_data(cb, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, sizeof(cb1_data), &cb1_data);
17212     update_buffer_data(cb, 2 * D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, sizeof(cb2_data), &cb2_data);
17213     cbv_desc.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(cb);
17214     cbv_desc.SizeInBytes = D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT;
17215     for (i = 0; i < 3; ++i)
17216     {
17217         ID3D12Device_CreateConstantBufferView(context.device, &cbv_desc, cpu_handle);
17218         cbv_desc.BufferLocation += D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT;
17219         cpu_handle.ptr += descriptor_size;
17220     }
17221 
17222     /* create SRVs */
17223     cpu_handle = get_cpu_descriptor_handle(&context, cpu_heap, 10);
17224 
17225     t[0] = create_default_texture(context.device,
17226             1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
17227     data.pData = &t0_data;
17228     data.RowPitch = sizeof(t0_data);
17229     data.SlicePitch = data.RowPitch;
17230     upload_texture_data(t[0], &data, 1, queue, command_list);
17231     reset_command_list(command_list, context.allocator);
17232     transition_resource_state(command_list, t[0],
17233             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
17234 
17235     t[1] = create_default_texture(context.device,
17236             1, 1, DXGI_FORMAT_R32_UINT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
17237     data.pData = &t1_data;
17238     data.RowPitch = sizeof(t1_data);
17239     data.SlicePitch = data.RowPitch;
17240     upload_texture_data(t[1], &data, 1, queue, command_list);
17241     reset_command_list(command_list, context.allocator);
17242     transition_resource_state(command_list, t[1],
17243             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
17244 
17245     t[2] = create_default_texture(context.device,
17246             1, 1, DXGI_FORMAT_R32_SINT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
17247     data.pData = &t2_data;
17248     data.RowPitch = sizeof(t2_data);
17249     data.SlicePitch = data.RowPitch;
17250     upload_texture_data(t[2], &data, 1, queue, command_list);
17251     reset_command_list(command_list, context.allocator);
17252     transition_resource_state(command_list, t[2],
17253             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
17254 
17255     t[3] = create_default_buffer(device, sizeof(t3_data),
17256             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
17257     upload_buffer_data(t[3], 0, sizeof(t3_data), &t3_data, queue, command_list);
17258     reset_command_list(command_list, context.allocator);
17259     transition_resource_state(command_list, t[3],
17260             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
17261 
17262     t[4] = create_default_buffer(device, sizeof(t4_data),
17263             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
17264     upload_buffer_data(t[4], 0, sizeof(t4_data), &t4_data, queue, command_list);
17265     reset_command_list(command_list, context.allocator);
17266     transition_resource_state(command_list, t[4],
17267             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
17268 
17269     t[5] = create_default_buffer(device, sizeof(t5_data),
17270             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
17271     upload_buffer_data(t[5], 0, sizeof(t5_data), &t5_data, queue, command_list);
17272     reset_command_list(command_list, context.allocator);
17273     transition_resource_state(command_list, t[5],
17274             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
17275 
17276     init_depth_stencil(&ds, device, 32, 32, 1, 1, DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_D32_FLOAT, NULL);
17277     t[6] = ds.texture;
17278     ID3D12Resource_AddRef(t[6]);
17279     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
17280             D3D12_CLEAR_FLAG_DEPTH, 0.5f, 0, 0, NULL);
17281     transition_resource_state(command_list, t[6],
17282             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
17283 
17284     for (i = 0; i < 3; ++i)
17285     {
17286         ID3D12Device_CreateShaderResourceView(device, t[i], NULL, cpu_handle);
17287         cpu_handle.ptr += descriptor_size;
17288     }
17289 
17290     memset(&srv_desc, 0, sizeof(srv_desc));
17291     srv_desc.Format = DXGI_FORMAT_R32_FLOAT;
17292     srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
17293     srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
17294     srv_desc.Buffer.FirstElement = 0;
17295     srv_desc.Buffer.NumElements = 1;
17296     ID3D12Device_CreateShaderResourceView(device, t[3], &srv_desc, cpu_handle);
17297     cpu_handle.ptr += descriptor_size;
17298 
17299     srv_desc.Format = DXGI_FORMAT_UNKNOWN;
17300     srv_desc.Buffer.StructureByteStride = sizeof(t4_data);
17301     ID3D12Device_CreateShaderResourceView(device, t[4], &srv_desc, cpu_handle);
17302     cpu_handle.ptr += descriptor_size;
17303 
17304     srv_desc.Format = DXGI_FORMAT_R32_TYPELESS;
17305     srv_desc.Buffer.NumElements = 4;
17306     srv_desc.Buffer.StructureByteStride = 0;
17307     srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
17308     ID3D12Device_CreateShaderResourceView(device, t[5], &srv_desc, cpu_handle);
17309     cpu_handle.ptr += descriptor_size;
17310 
17311     memset(&srv_desc, 0, sizeof(srv_desc));
17312     srv_desc.Format = DXGI_FORMAT_R32_FLOAT;
17313     srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
17314     srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
17315     srv_desc.Texture2D.MipLevels = 1;
17316     ID3D12Device_CreateShaderResourceView(device, t[6], &srv_desc, cpu_handle);
17317 
17318     /* create UAVs */
17319     cpu_handle = get_cpu_descriptor_handle(&context, cpu_heap, 20);
17320 
17321     u[0] = create_default_buffer(device, sizeof(u0_data),
17322             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
17323     upload_buffer_data(u[0], 0, sizeof(u0_data), &u0_data, queue, command_list);
17324     reset_command_list(command_list, context.allocator);
17325     transition_resource_state(command_list, u[0],
17326             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
17327     u[1] = create_default_buffer(device, sizeof(struct uvec4),
17328             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
17329     upload_buffer_data(u[1], 0, sizeof(u1_data), &u1_data, queue, command_list);
17330     reset_command_list(command_list, context.allocator);
17331     transition_resource_state(command_list, u[0],
17332             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
17333     u[2] = create_default_buffer(device, 44 * 4,
17334             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
17335 
17336     memset(&uav_desc, 0, sizeof(uav_desc));
17337     uav_desc.Format = DXGI_FORMAT_R32_TYPELESS;
17338     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
17339     uav_desc.Buffer.FirstElement = 0;
17340     uav_desc.Buffer.NumElements = 4;
17341     uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
17342     ID3D12Device_CreateUnorderedAccessView(device, u[0], NULL, &uav_desc, cpu_handle);
17343     cpu_handle.ptr += descriptor_size;
17344 
17345     uav_desc.Format = DXGI_FORMAT_UNKNOWN;
17346     uav_desc.Buffer.NumElements = 1;
17347     uav_desc.Buffer.StructureByteStride = sizeof(u1_data);
17348     uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
17349     ID3D12Device_CreateUnorderedAccessView(device, u[1], NULL, &uav_desc, cpu_handle);
17350     cpu_handle.ptr += descriptor_size;
17351 
17352     uav_desc.Format = DXGI_FORMAT_R32_TYPELESS;
17353     uav_desc.Buffer.NumElements = 44;
17354     uav_desc.Buffer.StructureByteStride = 0;
17355     uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
17356     ID3D12Device_CreateUnorderedAccessView(device, u[2], NULL, &uav_desc, cpu_handle);
17357 
17358     /* root signature */
17359     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
17360     descriptor_ranges[0].NumDescriptors = 3;
17361     descriptor_ranges[0].BaseShaderRegister = 0;
17362     descriptor_ranges[0].RegisterSpace = 0;
17363     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
17364     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
17365     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
17366     root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_ranges[0];
17367     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
17368     descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
17369     descriptor_ranges[1].NumDescriptors = 4;
17370     descriptor_ranges[1].BaseShaderRegister = 0;
17371     descriptor_ranges[1].RegisterSpace = 0;
17372     descriptor_ranges[1].OffsetInDescriptorsFromTableStart = 0;
17373     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
17374     root_parameters[1].DescriptorTable.NumDescriptorRanges = 1;
17375     root_parameters[1].DescriptorTable.pDescriptorRanges = &descriptor_ranges[1];
17376     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
17377     descriptor_ranges[2].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
17378     descriptor_ranges[2].NumDescriptors = 7;
17379     descriptor_ranges[2].BaseShaderRegister = 0;
17380     descriptor_ranges[2].RegisterSpace = 0;
17381     descriptor_ranges[2].OffsetInDescriptorsFromTableStart = 0;
17382     root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
17383     root_parameters[2].DescriptorTable.NumDescriptorRanges = 1;
17384     root_parameters[2].DescriptorTable.pDescriptorRanges = &descriptor_ranges[2];
17385     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
17386     descriptor_ranges[3].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
17387     descriptor_ranges[3].NumDescriptors = 2;
17388     descriptor_ranges[3].BaseShaderRegister = 0;
17389     descriptor_ranges[3].RegisterSpace = 0;
17390     descriptor_ranges[3].OffsetInDescriptorsFromTableStart = 0;
17391     descriptor_ranges[4].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
17392     descriptor_ranges[4].NumDescriptors = 1;
17393     descriptor_ranges[4].BaseShaderRegister = 2;
17394     descriptor_ranges[4].RegisterSpace = 0;
17395     descriptor_ranges[4].OffsetInDescriptorsFromTableStart = 2;
17396     root_parameters[3].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
17397     root_parameters[3].DescriptorTable.NumDescriptorRanges = 2;
17398     root_parameters[3].DescriptorTable.pDescriptorRanges = &descriptor_ranges[3];
17399     root_parameters[3].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
17400     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
17401     root_signature_desc.NumParameters = 4;
17402     root_signature_desc.pParameters = root_parameters;
17403     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
17404     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
17405 
17406     context.pipeline_state = create_compute_pipeline_state(device, context.root_signature,
17407             shader_bytecode(cs_code, sizeof(cs_code)));
17408 
17409     /* copy descriptors */
17410     dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 5);
17411     dst_range_sizes[0] = 2;
17412     src_handles[0] = get_cpu_descriptor_handle(&context, cpu_heap, 0);
17413     src_range_sizes[0] = 2;
17414     /* cb0-cb1 */
17415     ID3D12Device_CopyDescriptors(device, 1, dst_handles, dst_range_sizes,
17416             1, src_handles, src_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17417     dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 7);
17418     dst_range_sizes[0] = 1;
17419     src_handles[0] = get_cpu_descriptor_handle(&context, cpu_heap, 2);
17420     src_range_sizes[0] = 1;
17421     /* cb2 */
17422     ID3D12Device_CopyDescriptors(device, 1, dst_handles, dst_range_sizes,
17423             1, src_handles, src_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17424 
17425     ID3D12Device_CopyDescriptorsSimple(device, 2,
17426             get_cpu_sampler_handle(&context, cpu_sampler_heap2, 0),
17427             get_cpu_sampler_handle(&context, cpu_sampler_heap, 0),
17428             D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
17429 
17430     dst_handles[0] = get_cpu_sampler_handle(&context, sampler_heap, 0);
17431     dst_range_sizes[0] = 4;
17432     src_handles[0] = get_cpu_sampler_handle(&context, cpu_sampler_heap2, 0);
17433     src_handles[1] = get_cpu_sampler_handle(&context, cpu_sampler_heap2, 0);
17434     src_handles[2] = get_cpu_sampler_handle(&context, cpu_sampler_heap2, 0);
17435     src_handles[3] = get_cpu_sampler_handle(&context, cpu_sampler_heap2, 1);
17436     /* s0-s3 */
17437     ID3D12Device_CopyDescriptors(device, 1, dst_handles, dst_range_sizes,
17438             4, src_handles, NULL, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
17439 
17440     dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 9);
17441     dst_range_sizes[0] = 4;
17442     dst_handles[1] = get_cpu_descriptor_handle(&context, heap, 9);
17443     dst_range_sizes[1] = 0;
17444     dst_handles[2] = get_cpu_descriptor_handle(&context, heap, 13);
17445     dst_range_sizes[2] = 3;
17446     dst_handles[3] = get_cpu_descriptor_handle(&context, heap, 13);
17447     dst_range_sizes[3] = 0;
17448     src_handles[0] = get_cpu_descriptor_handle(&context, cpu_heap, 10);
17449     src_range_sizes[0] = 8;
17450     /* t0-t6 */
17451     ID3D12Device_CopyDescriptors(device, 4, dst_handles, dst_range_sizes,
17452             1, src_handles, src_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17453 
17454     /* copy 1 uninitialized descriptor (19) */
17455     dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 19);
17456     dst_range_sizes[0] = 2;
17457     dst_handles[1] = get_cpu_descriptor_handle(&context, heap, 21);
17458     dst_range_sizes[1] = 1;
17459     src_handles[0] = get_cpu_descriptor_handle(&context, cpu_heap, 19);
17460     src_range_sizes[0] = 2;
17461     src_handles[1] = get_cpu_descriptor_handle(&context, cpu_heap, 21);
17462     src_range_sizes[1] = 1;
17463     /* u1-u2 */
17464     ID3D12Device_CopyDescriptors(device, 2, dst_handles, dst_range_sizes,
17465             2, src_handles, src_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17466 
17467     /* u2 */
17468     ID3D12Device_CopyDescriptorsSimple(device, 1,
17469             get_cpu_descriptor_handle(&context, heap, 22),
17470             get_cpu_descriptor_handle(&context, cpu_heap, 22),
17471             D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17472 
17473     /* range sizes equal to 0 */
17474     dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 19);
17475     dst_range_sizes[0] = 0;
17476     dst_handles[1] = get_cpu_descriptor_handle(&context, heap, 19);
17477     dst_range_sizes[1] = 0;
17478     src_handles[0] = get_cpu_descriptor_handle(&context, cpu_heap, 0);
17479     src_range_sizes[0] = 1;
17480     src_handles[1] = get_cpu_descriptor_handle(&context, cpu_heap, 0);
17481     src_range_sizes[1] = 4;
17482     ID3D12Device_CopyDescriptors(device, 2, dst_handles, dst_range_sizes,
17483             2, src_handles, src_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17484     dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 19);
17485     dst_range_sizes[0] = 4;
17486     dst_handles[1] = get_cpu_descriptor_handle(&context, heap, 19);
17487     dst_range_sizes[1] = 4;
17488     src_handles[0] = get_cpu_descriptor_handle(&context, cpu_heap, 0);
17489     src_range_sizes[0] = 0;
17490     src_handles[1] = get_cpu_descriptor_handle(&context, cpu_heap, 0);
17491     src_range_sizes[1] = 0;
17492     ID3D12Device_CopyDescriptors(device, 2, dst_handles, dst_range_sizes,
17493             2, src_handles, src_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17494 
17495     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
17496     heaps[0] = sampler_heap; heaps[1] = heap;
17497     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, ARRAY_SIZE(heaps), heaps);
17498     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0,
17499             get_gpu_descriptor_handle(&context, heap, 5));
17500     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 1,
17501             get_gpu_sampler_handle(&context, sampler_heap, 0));
17502     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 2,
17503             get_gpu_descriptor_handle(&context, heap, 9));
17504     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 3,
17505             get_gpu_descriptor_handle(&context, heap, 20));
17506 
17507     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
17508     ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
17509 
17510     transition_sub_resource_state(command_list, u[2], 0,
17511             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
17512     get_buffer_readback_with_command_list(u[2], DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
17513     result = get_readback_data(&rb, 0, 0, 0, sizeof(*result));
17514     ok(result[ 0] == cb0_data, "Got unexpected value %#x.\n", result[0]);
17515     ok(result[ 1] == cb1_data, "Got unexpected value %#x.\n", result[1]);
17516     ok(result[ 2] == cb2_data, "Got unexpected value %#x.\n", result[2]);
17517     ok(result[ 3] == 0, "Got unexpected value %#x.\n", result[3]);
17518     ok(result[ 4] == t0_data.x, "Got unexpected value %#x.\n", result[4]);
17519     ok(result[ 5] == t0_data.y, "Got unexpected value %#x.\n", result[5]);
17520     ok(result[ 6] == t0_data.z, "Got unexpected value %#x.\n", result[6]);
17521     ok(result[ 7] == t0_data.w, "Got unexpected value %#x.\n", result[7]);
17522     ok(result[ 8] == t0_data.x, "Got unexpected value %#x.\n", result[8]);
17523     ok(result[ 9] == t0_data.y, "Got unexpected value %#x.\n", result[9]);
17524     ok(result[10] == t0_data.z, "Got unexpected value %#x.\n", result[10]);
17525     ok(result[11] == t0_data.w, "Got unexpected value %#x.\n", result[11]);
17526     ok(result[12] == t0_data.x, "Got unexpected value %#x.\n", result[12]);
17527     ok(result[13] == t0_data.y, "Got unexpected value %#x.\n", result[13]);
17528     ok(result[14] == t0_data.z, "Got unexpected value %#x.\n", result[14]);
17529     ok(result[15] == t0_data.w, "Got unexpected value %#x.\n", result[15]);
17530     ok(result[16] == t1_data, "Got unexpected value %#x.\n", result[16]);
17531     ok(result[17] == t2_data, "Got unexpected value %#x.\n", result[17]);
17532     ok(result[18] == (unsigned int)t3_data, "Got unexpected value %#x.\n", result[18]);
17533     ok(result[19] == (unsigned int)t4_data, "Got unexpected value %#x.\n", result[19]);
17534     ok(result[20] == t5_data.x, "Got unexpected value %#x.\n", result[20]);
17535     ok(result[21] == t5_data.y, "Got unexpected value %#x.\n", result[21]);
17536     ok(result[22] == t5_data.z, "Got unexpected value %#x.\n", result[22]);
17537     ok(result[23] == t5_data.w, "Got unexpected value %#x.\n", result[23]);
17538     ok(result[24] == 1, "Got unexpected value %#x.\n", result[24]);
17539     ok(result[25] == 1, "Got unexpected value %#x.\n", result[25]);
17540     ok(result[26] == 1, "Got unexpected value %#x.\n", result[26]);
17541     ok(result[27] == 1, "Got unexpected value %#x.\n", result[27]);
17542     ok(result[28] == 0, "Got unexpected value %#x.\n", result[28]);
17543     ok(result[29] == 0, "Got unexpected value %#x.\n", result[29]);
17544     ok(result[30] == 0, "Got unexpected value %#x.\n", result[30]);
17545     ok(result[31] == 0, "Got unexpected value %#x.\n", result[31]);
17546     ok(result[32] == u0_data.x, "Got unexpected value %#x.\n", result[32]);
17547     ok(result[33] == u0_data.y, "Got unexpected value %#x.\n", result[33]);
17548     ok(result[34] == u0_data.z, "Got unexpected value %#x.\n", result[34]);
17549     ok(result[35] == u0_data.w, "Got unexpected value %#x.\n", result[35]);
17550     ok(result[36] == u1_data.u[0], "Got unexpected value %#x.\n", result[36]);
17551     ok(result[37] == u1_data.u[1], "Got unexpected value %#x.\n", result[37]);
17552     ok(result[38] == u1_data.u[2], "Got unexpected value %#x.\n", result[38]);
17553     ok(result[39] == u1_data.f, "Got unexpected value %#x.\n", result[39]);
17554     ok(result[40] == u1_data.f, "Got unexpected value %#x.\n", result[40]);
17555     ok(result[41] == u1_data.f, "Got unexpected value %#x.\n", result[41]);
17556     ok(result[42] == u1_data.f, "Got unexpected value %#x.\n", result[42]);
17557     ok(result[43] == 0xdeadbeef, "Got unexpected value %#x.\n", result[43]);
17558     assert(rb.width == 44);
17559     release_resource_readback(&rb);
17560 
17561     ID3D12DescriptorHeap_Release(cpu_heap);
17562     ID3D12DescriptorHeap_Release(cpu_sampler_heap);
17563     ID3D12DescriptorHeap_Release(cpu_sampler_heap2);
17564     ID3D12DescriptorHeap_Release(heap);
17565     ID3D12DescriptorHeap_Release(sampler_heap);
17566     ID3D12Resource_Release(cb);
17567     for (i = 0; i < ARRAY_SIZE(t); ++i)
17568         ID3D12Resource_Release(t[i]);
17569     for (i = 0; i < ARRAY_SIZE(u); ++i)
17570         ID3D12Resource_Release(u[i]);
17571     destroy_depth_stencil(&ds);
17572     destroy_test_context(&context);
17573 }
17574 
test_copy_descriptors_range_sizes(void)17575 static void test_copy_descriptors_range_sizes(void)
17576 {
17577     D3D12_CPU_DESCRIPTOR_HANDLE dst_handles[1], src_handles[1];
17578     D3D12_CPU_DESCRIPTOR_HANDLE green_handle, blue_handle;
17579     ID3D12Resource *green_texture, *blue_texture;
17580     UINT dst_range_sizes[1], src_range_sizes[1];
17581     ID3D12GraphicsCommandList *command_list;
17582     ID3D12DescriptorHeap *cpu_heap;
17583     struct test_context_desc desc;
17584     D3D12_SUBRESOURCE_DATA data;
17585     struct resource_readback rb;
17586     struct test_context context;
17587     ID3D12DescriptorHeap *heap;
17588     ID3D12CommandQueue *queue;
17589     ID3D12Device *device;
17590     unsigned int i;
17591     D3D12_BOX box;
17592 
17593     static const DWORD ps_code[] =
17594     {
17595 #if 0
17596         Texture2D t;
17597         SamplerState s;
17598 
17599         float4 main(float4 position : SV_POSITION) : SV_Target
17600         {
17601             float2 p;
17602 
17603             p.x = position.x / 32.0f;
17604             p.y = position.y / 32.0f;
17605             return t.Sample(s, p);
17606         }
17607 #endif
17608         0x43425844, 0x7a0c3929, 0x75ff3ca4, 0xccb318b2, 0xe6965b4c, 0x00000001, 0x00000140, 0x00000003,
17609         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
17610         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
17611         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
17612         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000a4, 0x00000050,
17613         0x00000029, 0x0100086a, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000,
17614         0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
17615         0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002,
17616         0x3d000000, 0x3d000000, 0x00000000, 0x00000000, 0x8b000045, 0x800000c2, 0x00155543, 0x001020f2,
17617         0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0100003e,
17618     };
17619     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
17620     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
17621     static const struct vec4 green = {0.0f, 1.0f, 0.0f, 1.0f};
17622     static const struct vec4 blue = {0.0f, 0.0f, 1.0f, 1.0f};
17623 
17624     memset(&desc, 0, sizeof(desc));
17625     desc.rt_width = desc.rt_height = 6;
17626     desc.no_root_signature = true;
17627     if (!init_test_context(&context, &desc))
17628         return;
17629     device = context.device;
17630     command_list = context.list;
17631     queue = context.queue;
17632 
17633     cpu_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 10);
17634     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 8);
17635 
17636     green_handle = get_cpu_descriptor_handle(&context, cpu_heap, 0);
17637     blue_handle = get_cpu_descriptor_handle(&context, cpu_heap, 1);
17638 
17639     green_texture = create_default_texture(context.device,
17640             1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
17641     data.pData = &green;
17642     data.RowPitch = sizeof(green);
17643     data.SlicePitch = data.RowPitch;
17644     upload_texture_data(green_texture, &data, 1, queue, command_list);
17645     reset_command_list(command_list, context.allocator);
17646     transition_resource_state(command_list, green_texture,
17647             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
17648     ID3D12Device_CreateShaderResourceView(device, green_texture, NULL, green_handle);
17649 
17650     blue_texture = create_default_texture(context.device,
17651             1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
17652     data.pData = &blue;
17653     data.RowPitch = sizeof(blue);
17654     data.SlicePitch = data.RowPitch;
17655     upload_texture_data(blue_texture, &data, 1, queue, command_list);
17656     reset_command_list(command_list, context.allocator);
17657     transition_resource_state(command_list, blue_texture,
17658             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
17659     ID3D12Device_CreateShaderResourceView(device, blue_texture, NULL, blue_handle);
17660 
17661     context.root_signature = create_texture_root_signature(context.device,
17662             D3D12_SHADER_VISIBILITY_PIXEL, 0, 0);
17663     context.pipeline_state = create_pipeline_state(context.device,
17664             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
17665 
17666     /* copy descriptors */
17667     dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 1);
17668     dst_range_sizes[0] = 1;
17669     src_handles[0] = blue_handle;
17670     src_range_sizes[0] = 1;
17671     ID3D12Device_CopyDescriptors(device, 1, dst_handles, dst_range_sizes,
17672             1, src_handles, src_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17673 
17674     dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 2);
17675     dst_range_sizes[0] = 1;
17676     src_handles[0] = green_handle;
17677     src_range_sizes[0] = 1;
17678     ID3D12Device_CopyDescriptors(device, 1, dst_handles, dst_range_sizes,
17679             1, src_handles, src_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17680 
17681     dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 3);
17682     src_handles[0] = blue_handle;
17683     src_range_sizes[0] = 1;
17684     ID3D12Device_CopyDescriptors(device, 1, dst_handles, NULL,
17685             1, src_handles, src_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17686 
17687     dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 4);
17688     src_handles[0] = green_handle;
17689     src_range_sizes[0] = 1;
17690     ID3D12Device_CopyDescriptors(device, 1, dst_handles, NULL,
17691             1, src_handles, src_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17692 
17693     dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 5);
17694     src_handles[0] = blue_handle;
17695     ID3D12Device_CopyDescriptors(device, 1, dst_handles, NULL,
17696             1, src_handles, NULL, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17697 
17698     dst_handles[0] = get_cpu_descriptor_handle(&context, heap, 0);
17699     src_handles[0] = green_handle;
17700     ID3D12Device_CopyDescriptors(device, 1, dst_handles, NULL,
17701             1, src_handles, NULL, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
17702 
17703     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
17704 
17705     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
17706     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
17707     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
17708     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
17709     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
17710     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
17711 
17712     for (i = 0; i < desc.rt_width; ++i)
17713     {
17714         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
17715                 get_gpu_descriptor_handle(&context, heap, i));
17716         set_viewport(&context.viewport, i, 0.0f, 1.0f, desc.rt_height, 0.0f, 1.0f);
17717         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
17718         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
17719     }
17720 
17721     transition_resource_state(command_list, context.render_target,
17722             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
17723 
17724     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
17725     for (i = 0; i < desc.rt_width; ++i)
17726     {
17727         set_box(&box, i, 0, 0, i + 1, desc.rt_height, 1);
17728         check_readback_data_uint(&rb, &box, i % 2 ? 0xffff0000 : 0xff00ff00, 0);
17729     }
17730     release_resource_readback(&rb);
17731 
17732     ID3D12DescriptorHeap_Release(cpu_heap);
17733     ID3D12DescriptorHeap_Release(heap);
17734     ID3D12Resource_Release(blue_texture);
17735     ID3D12Resource_Release(green_texture);
17736     destroy_test_context(&context);
17737 }
17738 
test_descriptors_visibility(void)17739 static void test_descriptors_visibility(void)
17740 {
17741     ID3D12Resource *vs_raw_buffer, *ps_raw_buffer;
17742     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
17743     D3D12_DESCRIPTOR_RANGE descriptor_ranges[2];
17744     D3D12_STATIC_SAMPLER_DESC sampler_desc[2];
17745     ID3D12Resource *vs_texture, *ps_texture;
17746     ID3D12GraphicsCommandList *command_list;
17747     D3D12_ROOT_PARAMETER root_parameters[6];
17748     ID3D12Resource *vs_cb, *ps_cb;
17749     struct test_context_desc desc;
17750     D3D12_SUBRESOURCE_DATA data;
17751     struct test_context context;
17752     ID3D12DescriptorHeap *heap;
17753     ID3D12CommandQueue *queue;
17754     ID3D12Device *device;
17755     HRESULT hr;
17756 
17757     static const DWORD vs_code[] =
17758     {
17759 #if 0
17760         ByteAddressBuffer b;
17761         Texture2D t;
17762         SamplerState s;
17763 
17764         float4 cb;
17765 
17766         float4 main(uint id : SV_VertexID) : SV_Position
17767         {
17768             float2 coords = float2((id << 1) & 2, id & 2);
17769             uint i;
17770 
17771             if (cb.x != 4.0 || cb.y != 8.0 || cb.z != 16.0 || cb.w != 32.0)
17772                 return (float4)0;
17773 
17774             for (i = 0; i <= 6; ++i)
17775             {
17776                 if (b.Load(4 * i) != i)
17777                     return (float4)0;
17778             }
17779 
17780             if (any(t.SampleLevel(s, (float2)0, 0) != float4(1.0, 1.0, 0.0, 1.0)))
17781                 return (float4)0;
17782 
17783             return float4(coords * float2(2, -2) + float2(-1, 1), 0, 1);
17784         }
17785 #endif
17786         0x43425844, 0x046e4d13, 0xd2103a18, 0x8576703b, 0x6f58933a, 0x00000001, 0x0000043c, 0x00000003,
17787         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
17788         0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000101, 0x565f5653, 0x65747265, 0x00444978,
17789         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
17790         0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x58454853, 0x000003a0, 0x00010050,
17791         0x000000e8, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000,
17792         0x00000000, 0x030000a1, 0x00107000, 0x00000000, 0x04001858, 0x00107000, 0x00000001, 0x00005555,
17793         0x04000060, 0x00101012, 0x00000000, 0x00000006, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
17794         0x02000068, 0x00000002, 0x0b000039, 0x001000f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000,
17795         0x00004002, 0x40800000, 0x41000000, 0x41800000, 0x42000000, 0x0700003c, 0x00100012, 0x00000000,
17796         0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0700003c, 0x00100012, 0x00000000, 0x0010002a,
17797         0x00000000, 0x0010000a, 0x00000000, 0x0700003c, 0x00100012, 0x00000000, 0x0010003a, 0x00000000,
17798         0x0010000a, 0x00000000, 0x0304001f, 0x0010000a, 0x00000000, 0x08000036, 0x001020f2, 0x00000000,
17799         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e, 0x01000015, 0x05000036,
17800         0x00100012, 0x00000000, 0x00004001, 0x00000000, 0x01000030, 0x0700004f, 0x00100022, 0x00000000,
17801         0x00004001, 0x00000006, 0x0010000a, 0x00000000, 0x03040003, 0x0010001a, 0x00000000, 0x07000029,
17802         0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000002, 0x890000a5, 0x800002c2,
17803         0x00199983, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00107006, 0x00000000, 0x07000027,
17804         0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010001a,
17805         0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
17806         0x00000000, 0x0100003e, 0x01000015, 0x0700001e, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
17807         0x00004001, 0x00000001, 0x01000016, 0x90000048, 0x800000c2, 0x00155543, 0x001000f2, 0x00000000,
17808         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000001, 0x00106000,
17809         0x00000000, 0x00004001, 0x00000000, 0x0a000039, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
17810         0x00004002, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x0700003c, 0x00100032, 0x00000000,
17811         0x00100ae6, 0x00000000, 0x00100046, 0x00000000, 0x0700003c, 0x00100012, 0x00000000, 0x0010001a,
17812         0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a, 0x00000000, 0x08000036, 0x001020f2,
17813         0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e, 0x01000015,
17814         0x0b00008c, 0x00100012, 0x00000000, 0x00004001, 0x00000001, 0x00004001, 0x00000001, 0x0010100a,
17815         0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100022, 0x00000000, 0x0010100a, 0x00000000,
17816         0x00004001, 0x00000002, 0x05000056, 0x00100032, 0x00000001, 0x00100046, 0x00000000, 0x0f000032,
17817         0x00102032, 0x00000000, 0x00100046, 0x00000001, 0x00004002, 0x40000000, 0xc0000000, 0x00000000,
17818         0x00000000, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000, 0x08000036, 0x001020c2,
17819         0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e,
17820     };
17821     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
17822     static const DWORD ps_code[] =
17823     {
17824 #if 0
17825         ByteAddressBuffer b;
17826         Texture2D t;
17827         SamplerState s;
17828 
17829         float4 cb;
17830 
17831         float4 main(float4 position : SV_POSITION) : SV_Target
17832         {
17833             if (cb.x != 1.0 || cb.y != 2.0 || cb.z != 3.0 || cb.w != 4.0)
17834                 return float4(1.0, 0.0, 0.0, 1.0);
17835 
17836             if (b.Load(0) != 2 || b.Load(4) != 4 || b.Load(8) != 8)
17837                 return float4(1.0, 0.0, 0.0, 1.0);
17838 
17839             return t.Sample(s, float2(position.x / 32.0, position.y / 32.0));
17840         }
17841 #endif
17842         0x43425844, 0x1b1aafc1, 0xeab215f6, 0x77d65b25, 0x03cbe695, 0x00000001, 0x000002dc, 0x00000003,
17843         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
17844         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
17845         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
17846         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000240, 0x00000050,
17847         0x00000090, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300005a, 0x00106000,
17848         0x00000000, 0x030000a1, 0x00107000, 0x00000000, 0x04001858, 0x00107000, 0x00000001, 0x00005555,
17849         0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
17850         0x00000001, 0x0b000039, 0x001000f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00004002,
17851         0x3f800000, 0x40000000, 0x40400000, 0x40800000, 0x0700003c, 0x00100012, 0x00000000, 0x0010001a,
17852         0x00000000, 0x0010000a, 0x00000000, 0x0700003c, 0x00100012, 0x00000000, 0x0010002a, 0x00000000,
17853         0x0010000a, 0x00000000, 0x0700003c, 0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x0010000a,
17854         0x00000000, 0x0304001f, 0x0010000a, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002,
17855         0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e, 0x01000015, 0x890000a5, 0x800002c2,
17856         0x00199983, 0x00100072, 0x00000000, 0x00004001, 0x00000000, 0x00107246, 0x00000000, 0x0a000027,
17857         0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00004002, 0x00000002, 0x00000004, 0x00000008,
17858         0x00000000, 0x0700003c, 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000,
17859         0x0700003c, 0x00100012, 0x00000000, 0x0010002a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f,
17860         0x0010000a, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x3f800000, 0x00000000,
17861         0x00000000, 0x3f800000, 0x0100003e, 0x01000015, 0x0a000038, 0x00100032, 0x00000000, 0x00101046,
17862         0x00000000, 0x00004002, 0x3d000000, 0x3d000000, 0x00000000, 0x00000000, 0x8b000045, 0x800000c2,
17863         0x00155543, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000001, 0x00106000,
17864         0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x0100003e,
17865     };
17866     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
17867     static const struct vec4 vs_cb_data = {4.0f, 8.0f, 16.0f, 32.0f};
17868     static const struct vec4 ps_cb_data = {1.0f, 2.0f, 3.0f, 4.0f};
17869     static const uint32_t vs_buffer_data[] = {0, 1, 2, 3, 4, 5, 6};
17870     static const uint32_t ps_buffer_data[] = {2, 4, 8};
17871     static const float vs_texture_data[] = {1.0f, 1.0f, 0.0f, 1.0f};
17872     static const float ps_texture_data[] = {0.0f, 1.0f, 0.0f, 1.0f};
17873     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
17874 
17875     memset(&desc, 0, sizeof(desc));
17876     desc.no_root_signature = true;
17877     if (!init_test_context(&context, &desc))
17878         return;
17879     device = context.device;
17880     command_list = context.list;
17881     queue = context.queue;
17882 
17883     sampler_desc[0].Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
17884     sampler_desc[0].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
17885     sampler_desc[0].AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
17886     sampler_desc[0].AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
17887     sampler_desc[0].MipLODBias = 0.0f;
17888     sampler_desc[0].MaxAnisotropy = 0;
17889     sampler_desc[0].ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
17890     sampler_desc[0].BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE;
17891     sampler_desc[0].MinLOD = 0.0f;
17892     sampler_desc[0].MaxLOD = 0.0f;
17893     sampler_desc[0].ShaderRegister = 0;
17894     sampler_desc[0].RegisterSpace = 0;
17895     sampler_desc[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
17896 
17897     sampler_desc[1] = sampler_desc[0];
17898     sampler_desc[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
17899 
17900     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
17901     root_parameters[0].Descriptor.ShaderRegister = 0;
17902     root_parameters[0].Descriptor.RegisterSpace = 0;
17903     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
17904     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
17905     root_parameters[1].Descriptor.ShaderRegister = 0;
17906     root_parameters[1].Descriptor.RegisterSpace = 0;
17907     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
17908     root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
17909     root_parameters[2].Descriptor.ShaderRegister = 0;
17910     root_parameters[2].Descriptor.RegisterSpace = 0;
17911     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
17912     root_parameters[3].ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
17913     root_parameters[3].Descriptor.ShaderRegister = 0;
17914     root_parameters[3].Descriptor.RegisterSpace = 0;
17915     root_parameters[3].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
17916     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
17917     descriptor_ranges[0].NumDescriptors = 1;
17918     descriptor_ranges[0].BaseShaderRegister = 1;
17919     descriptor_ranges[0].RegisterSpace = 0;
17920     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
17921     root_parameters[4].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
17922     root_parameters[4].DescriptorTable.NumDescriptorRanges = 1;
17923     root_parameters[4].DescriptorTable.pDescriptorRanges = &descriptor_ranges[0];
17924     root_parameters[4].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
17925     descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
17926     descriptor_ranges[1].NumDescriptors = 1;
17927     descriptor_ranges[1].BaseShaderRegister = 1;
17928     descriptor_ranges[1].RegisterSpace = 0;
17929     descriptor_ranges[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
17930     root_parameters[5].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
17931     root_parameters[5].DescriptorTable.NumDescriptorRanges = 1;
17932     root_parameters[5].DescriptorTable.pDescriptorRanges = &descriptor_ranges[1];
17933     root_parameters[5].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
17934     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
17935     root_signature_desc.NumParameters = 6;
17936     root_signature_desc.pParameters = root_parameters;
17937     root_signature_desc.NumStaticSamplers = 2;
17938     root_signature_desc.pStaticSamplers = sampler_desc;
17939     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
17940     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
17941 
17942     context.pipeline_state = create_pipeline_state(device,
17943             context.root_signature, context.render_target_desc.Format,
17944             &vs, &ps, NULL);
17945 
17946     vs_cb = create_upload_buffer(device, sizeof(vs_cb_data), &vs_cb_data);
17947     ps_cb = create_upload_buffer(device, sizeof(ps_cb_data), &ps_cb_data);
17948 
17949     vs_raw_buffer = create_upload_buffer(device, sizeof(vs_buffer_data), vs_buffer_data);
17950     ps_raw_buffer = create_upload_buffer(device, sizeof(ps_buffer_data), ps_buffer_data);
17951 
17952     vs_texture = create_default_texture(device,
17953             1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
17954     data.pData = vs_texture_data;
17955     data.RowPitch = sizeof(vs_texture_data);
17956     data.SlicePitch = data.RowPitch;
17957     upload_texture_data(vs_texture, &data, 1, queue, command_list);
17958     reset_command_list(command_list, context.allocator);
17959     transition_resource_state(command_list, vs_texture,
17960             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
17961 
17962     ps_texture = create_default_texture(device,
17963             1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
17964     data.pData = ps_texture_data;
17965     data.RowPitch = sizeof(ps_texture_data);
17966     data.SlicePitch = data.RowPitch;
17967     upload_texture_data(ps_texture, &data, 1, queue, command_list);
17968     reset_command_list(command_list, context.allocator);
17969     transition_resource_state(command_list, ps_texture,
17970             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
17971 
17972     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
17973     ID3D12Device_CreateShaderResourceView(device, vs_texture, NULL,
17974             get_cpu_descriptor_handle(&context, heap, 0));
17975     ID3D12Device_CreateShaderResourceView(device, ps_texture, NULL,
17976             get_cpu_descriptor_handle(&context, heap, 1));
17977 
17978     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
17979     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
17980     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list,
17981             0, ID3D12Resource_GetGPUVirtualAddress(vs_cb));
17982     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list,
17983             1, ID3D12Resource_GetGPUVirtualAddress(ps_cb));
17984     ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(command_list,
17985             2, ID3D12Resource_GetGPUVirtualAddress(vs_raw_buffer));
17986     ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(command_list,
17987             3, ID3D12Resource_GetGPUVirtualAddress(ps_raw_buffer));
17988     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list,
17989             4, get_gpu_descriptor_handle(&context, heap, 0));
17990     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list,
17991             5, get_gpu_descriptor_handle(&context, heap, 1));
17992 
17993     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
17994     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
17995     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
17996     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
17997     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
17998 
17999     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
18000     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
18001 
18002     transition_resource_state(command_list, context.render_target,
18003             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
18004     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
18005 
18006     ID3D12Resource_Release(vs_cb);
18007     ID3D12Resource_Release(ps_cb);
18008     ID3D12Resource_Release(vs_texture);
18009     ID3D12Resource_Release(ps_texture);
18010     ID3D12Resource_Release(vs_raw_buffer);
18011     ID3D12Resource_Release(ps_raw_buffer);
18012     ID3D12DescriptorHeap_Release(heap);
18013     destroy_test_context(&context);
18014 }
18015 
test_create_null_descriptors(void)18016 static void test_create_null_descriptors(void)
18017 {
18018     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
18019     D3D12_CONSTANT_BUFFER_VIEW_DESC cbv_desc;
18020     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
18021     D3D12_DESCRIPTOR_HEAP_DESC heap_desc;
18022     struct test_context_desc desc;
18023     struct test_context context;
18024     ID3D12DescriptorHeap *heap;
18025     ID3D12Device *device;
18026     HRESULT hr;
18027 
18028     memset(&desc, 0, sizeof(desc));
18029     desc.no_root_signature = true;
18030     if (!init_test_context(&context, &desc))
18031         return;
18032     device = context.device;
18033 
18034     heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
18035     heap_desc.NumDescriptors = 16;
18036     heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
18037     heap_desc.NodeMask = 0;
18038     hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc,
18039             &IID_ID3D12DescriptorHeap, (void **)&heap);
18040     ok(SUCCEEDED(hr), "Failed to create descriptor heap, hr %#x.\n", hr);
18041 
18042     cbv_desc.BufferLocation = 0;
18043     cbv_desc.SizeInBytes = 0;
18044     ID3D12Device_CreateConstantBufferView(device, &cbv_desc,
18045             get_cpu_descriptor_handle(&context, heap, 0));
18046 
18047     memset(&srv_desc, 0, sizeof(srv_desc));
18048     srv_desc.Format = DXGI_FORMAT_R32_TYPELESS;
18049     srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
18050     srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
18051     srv_desc.Buffer.FirstElement = 0;
18052     srv_desc.Buffer.NumElements = 1;
18053     srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
18054     ID3D12Device_CreateShaderResourceView(device, NULL, &srv_desc,
18055             get_cpu_descriptor_handle(&context, heap, 1));
18056 
18057     memset(&srv_desc, 0, sizeof(srv_desc));
18058     srv_desc.Format = DXGI_FORMAT_R32_FLOAT;
18059     srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
18060     srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
18061     srv_desc.Texture2D.MipLevels = 1;
18062     ID3D12Device_CreateShaderResourceView(device, NULL, &srv_desc,
18063             get_cpu_descriptor_handle(&context, heap, 2));
18064 
18065     memset(&uav_desc, 0, sizeof(uav_desc));
18066     uav_desc.Format = DXGI_FORMAT_R32_UINT;
18067     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
18068     uav_desc.Buffer.FirstElement = 0;
18069     uav_desc.Buffer.NumElements = 1;
18070     ID3D12Device_CreateUnorderedAccessView(device, NULL, NULL, &uav_desc,
18071             get_cpu_descriptor_handle(&context, heap, 3));
18072 
18073     memset(&uav_desc, 0, sizeof(uav_desc));
18074     uav_desc.Format = DXGI_FORMAT_R32_UINT;
18075     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
18076     uav_desc.Texture2D.MipSlice = 0;
18077     uav_desc.Texture2D.PlaneSlice = 0;
18078     ID3D12Device_CreateUnorderedAccessView(device, NULL, NULL, &uav_desc,
18079             get_cpu_descriptor_handle(&context, heap, 3));
18080 
18081     ID3D12DescriptorHeap_Release(heap);
18082     destroy_test_context(&context);
18083 }
18084 
test_null_cbv(void)18085 static void test_null_cbv(void)
18086 {
18087     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
18088     D3D12_CONSTANT_BUFFER_VIEW_DESC cbv_desc;
18089     ID3D12GraphicsCommandList *command_list;
18090     D3D12_ROOT_PARAMETER root_parameters[2];
18091     D3D12_DESCRIPTOR_RANGE descriptor_range;
18092     struct test_context_desc desc;
18093     struct test_context context;
18094     ID3D12DescriptorHeap *heap;
18095     ID3D12CommandQueue *queue;
18096     ID3D12Device *device;
18097     unsigned int index;
18098     HRESULT hr;
18099 
18100     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
18101     static const DWORD ps_code[] =
18102     {
18103 #if 0
18104         uint index;
18105 
18106         cbuffer null_cb
18107         {
18108             float4 data[1024];
18109         };
18110 
18111         float4 main() : SV_Target
18112         {
18113             return data[index];
18114         }
18115 #endif
18116         0x43425844, 0xa69026e2, 0xccf934be, 0x11f0a922, 0x95e9ab51, 0x00000001, 0x000000f0, 0x00000003,
18117         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
18118         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
18119         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000078, 0x00000050, 0x0000001e,
18120         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000859, 0x00208e46, 0x00000001,
18121         0x00000400, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x06000036, 0x00100012,
18122         0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x07000036, 0x001020f2, 0x00000000, 0x04208e46,
18123         0x00000001, 0x0010000a, 0x00000000, 0x0100003e,
18124     };
18125     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
18126 
18127     memset(&desc, 0, sizeof(desc));
18128     desc.no_root_signature = true;
18129     if (!init_test_context(&context, &desc))
18130         return;
18131     command_list = context.list;
18132     queue = context.queue;
18133     device = context.device;
18134 
18135     descriptor_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
18136     descriptor_range.NumDescriptors = 1;
18137     descriptor_range.BaseShaderRegister = 1;
18138     descriptor_range.RegisterSpace = 0;
18139     descriptor_range.OffsetInDescriptorsFromTableStart = 0;
18140     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
18141     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
18142     root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_range;
18143     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
18144 
18145     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
18146     root_parameters[1].Constants.ShaderRegister = 0;
18147     root_parameters[1].Constants.RegisterSpace = 0;
18148     root_parameters[1].Constants.Num32BitValues = 1;
18149     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
18150 
18151     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
18152     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
18153     root_signature_desc.pParameters = root_parameters;
18154     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
18155     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
18156 
18157     context.pipeline_state = create_pipeline_state(context.device,
18158             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
18159 
18160     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 16);
18161 
18162     cbv_desc.BufferLocation = 0;
18163     cbv_desc.SizeInBytes = 0; /* Size doesn't appear to matter for NULL CBV. */
18164     ID3D12Device_CreateConstantBufferView(device, &cbv_desc,
18165             ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap));
18166 
18167     for (index = 0; index < 1200; index += 100)
18168     {
18169         vkd3d_test_set_context("index %u", index);
18170 
18171         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
18172 
18173         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
18174         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
18175         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
18176         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
18177         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
18178                 ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
18179         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 1, &index, 0);
18180         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
18181         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
18182         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
18183         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
18184 
18185         transition_sub_resource_state(command_list, context.render_target, 0,
18186                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
18187         check_sub_resource_uint(context.render_target, 0, queue, command_list, 0x00000000, 0);
18188 
18189         reset_command_list(command_list, context.allocator);
18190         transition_sub_resource_state(command_list, context.render_target, 0,
18191                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
18192     }
18193     vkd3d_test_set_context(NULL);
18194 
18195     ID3D12DescriptorHeap_Release(heap);
18196     destroy_test_context(&context);
18197 }
18198 
test_null_srv(void)18199 static void test_null_srv(void)
18200 {
18201     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
18202     ID3D12GraphicsCommandList *command_list;
18203     struct test_context_desc desc;
18204     struct test_context context;
18205     ID3D12DescriptorHeap *heap;
18206     ID3D12CommandQueue *queue;
18207     struct uvec4 location;
18208     ID3D12Device *device;
18209     unsigned int i, j;
18210 
18211     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
18212     static const DWORD ps_sample_code[] =
18213     {
18214 #if 0
18215         Texture2D t;
18216         SamplerState s;
18217 
18218         float4 main(float4 position : SV_Position) : SV_Target
18219         {
18220             return t.Sample(s, float2(position.x / 32.0f, position.y / 32.0f));
18221         }
18222 #endif
18223         0x43425844, 0xe096fa11, 0xeb01c081, 0x961588d4, 0x27c031af, 0x00000001, 0x00000140, 0x00000003,
18224         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
18225         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
18226         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
18227         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000a4, 0x00000050,
18228         0x00000029, 0x0100086a, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000,
18229         0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
18230         0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002,
18231         0x3d000000, 0x3d000000, 0x00000000, 0x00000000, 0x8b000045, 0x800000c2, 0x00155543, 0x001020f2,
18232         0x00000000, 0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0100003e,
18233     };
18234     static const D3D12_SHADER_BYTECODE ps_sample = {ps_sample_code, sizeof(ps_sample_code)};
18235     static const DWORD ps_ld_code[] =
18236     {
18237 #if 0
18238         Texture2D t;
18239 
18240         uint4 location;
18241 
18242         float4 main(float4 position : SV_Position) : SV_Target
18243         {
18244             return t.Load(location.xyz);
18245         }
18246 #endif
18247         0x43425844, 0xfa13670e, 0x291af510, 0xc253cc12, 0x9474950b, 0x00000001, 0x00000100, 0x00000003,
18248         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
18249         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69,
18250         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
18251         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000064, 0x00000050,
18252         0x00000019, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04001858, 0x00107000,
18253         0x00000000, 0x00005555, 0x03000065, 0x001020f2, 0x00000000, 0x8a00002d, 0x800000c2, 0x00155543,
18254         0x001020f2, 0x00000000, 0x00208a46, 0x00000000, 0x00000000, 0x00107e46, 0x00000000, 0x0100003e,
18255     };
18256     static const D3D12_SHADER_BYTECODE ps_ld = {ps_ld_code, sizeof(ps_ld_code)};
18257     static const DWORD ps_buffer_code[] =
18258     {
18259 #if 0
18260         ByteAddressBuffer t;
18261 
18262         uint location;
18263 
18264         float4 main(float4 position : SV_Position) : SV_Target
18265         {
18266             return t.Load(location);
18267         }
18268 #endif
18269         0x43425844, 0x70170f6b, 0x16097169, 0x714f155c, 0x1e3d860f, 0x00000001, 0x00000118, 0x00000003,
18270         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
18271         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69,
18272         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
18273         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000007c, 0x00000050,
18274         0x0000001f, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x030000a1, 0x00107000,
18275         0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x8a0000a5, 0x800002c2,
18276         0x00199983, 0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x00107006, 0x00000000,
18277         0x05000056, 0x001020f2, 0x00000000, 0x00100006, 0x00000000, 0x0100003e,
18278     };
18279     static const D3D12_SHADER_BYTECODE ps_buffer = {ps_buffer_code, sizeof(ps_buffer_code)};
18280     static const DXGI_FORMAT formats[] =
18281     {
18282         DXGI_FORMAT_R32_FLOAT,
18283         DXGI_FORMAT_R32_UINT,
18284         DXGI_FORMAT_R8G8B8A8_UNORM,
18285     };
18286     /* component mapping is ignored for NULL SRVs */
18287     static const unsigned int component_mappings[] =
18288     {
18289         D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
18290         D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
18291                 D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1,
18292                 D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1,
18293                 D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1,
18294                 D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1),
18295     };
18296 
18297     memset(&desc, 0, sizeof(desc));
18298     desc.no_root_signature = true;
18299     if (!init_test_context(&context, &desc))
18300         return;
18301     command_list = context.list;
18302     queue = context.queue;
18303     device = context.device;
18304 
18305     context.root_signature = create_texture_root_signature(context.device,
18306             D3D12_SHADER_VISIBILITY_PIXEL, 4, 0);
18307 
18308     context.pipeline_state = create_pipeline_state(context.device,
18309             context.root_signature, context.render_target_desc.Format, NULL, &ps_sample, NULL);
18310 
18311     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 16);
18312 
18313     for (i = 0; i < ARRAY_SIZE(formats); ++i)
18314     {
18315         for (j = 0; j < ARRAY_SIZE(component_mappings); ++j)
18316         {
18317             vkd3d_test_set_context("format %#x, component mapping %#x", formats[i], component_mappings[j]);
18318 
18319             memset(&srv_desc, 0, sizeof(srv_desc));
18320             srv_desc.Format = formats[i];
18321             srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
18322             srv_desc.Shader4ComponentMapping = component_mappings[j];
18323             srv_desc.Texture2D.MipLevels = 1;
18324             ID3D12Device_CreateShaderResourceView(device, NULL, &srv_desc,
18325                     ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap));
18326 
18327             ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
18328 
18329             ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
18330             ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
18331             ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
18332             ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
18333             ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
18334                     ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
18335             ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
18336             ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
18337             ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
18338             ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
18339 
18340             transition_sub_resource_state(command_list, context.render_target, 0,
18341                     D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
18342             check_sub_resource_uint(context.render_target, 0, queue, command_list, 0x00000000, 0);
18343 
18344             reset_command_list(command_list, context.allocator);
18345             transition_sub_resource_state(command_list, context.render_target, 0,
18346                     D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
18347         }
18348     }
18349     vkd3d_test_set_context(NULL);
18350 
18351     ID3D12PipelineState_Release(context.pipeline_state);
18352     context.pipeline_state = create_pipeline_state(context.device,
18353             context.root_signature, context.render_target_desc.Format, NULL, &ps_ld, NULL);
18354 
18355     memset(&srv_desc, 0, sizeof(srv_desc));
18356     srv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
18357     srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
18358     srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
18359     srv_desc.Texture2D.MipLevels = 1;
18360     ID3D12Device_CreateShaderResourceView(device, NULL, &srv_desc,
18361             ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap));
18362 
18363     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
18364 
18365     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
18366     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
18367     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
18368     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
18369     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
18370             ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
18371     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
18372     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
18373     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
18374     location.x = 10;
18375     location.y = 20;
18376     location.z = 0;
18377     location.w = 0;
18378     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &location, 0);
18379     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
18380 
18381     transition_sub_resource_state(command_list, context.render_target, 0,
18382             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
18383     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0x00000000, 0);
18384 
18385     /* buffer */
18386     ID3D12PipelineState_Release(context.pipeline_state);
18387     context.pipeline_state = create_pipeline_state(context.device,
18388             context.root_signature, context.render_target_desc.Format, NULL, &ps_buffer, NULL);
18389     reset_command_list(command_list, context.allocator);
18390     transition_sub_resource_state(command_list, context.render_target, 0,
18391             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
18392 
18393     memset(&srv_desc, 0, sizeof(srv_desc));
18394     srv_desc.Format = DXGI_FORMAT_R32_TYPELESS;
18395     srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
18396     srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
18397     srv_desc.Buffer.FirstElement = 0;
18398     srv_desc.Buffer.NumElements = 1024;
18399     srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
18400     ID3D12Device_CreateShaderResourceView(device, NULL, &srv_desc,
18401             ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap));
18402 
18403     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
18404 
18405     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
18406     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
18407     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
18408     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
18409     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
18410             ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
18411     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
18412     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
18413     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
18414     location.x = 0;
18415     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 4, &location, 0);
18416     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
18417 
18418     transition_sub_resource_state(command_list, context.render_target, 0,
18419             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
18420     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0x00000000, 0);
18421 
18422     ID3D12DescriptorHeap_Release(heap);
18423     destroy_test_context(&context);
18424 }
18425 
test_null_uav(void)18426 static void test_null_uav(void)
18427 {
18428     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
18429     D3D12_DESCRIPTOR_RANGE descriptor_ranges[1];
18430     D3D12_ROOT_PARAMETER root_parameters[2];
18431     const D3D12_SHADER_BYTECODE *current_ps;
18432     ID3D12GraphicsCommandList *command_list;
18433     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
18434     ID3D12DescriptorHeap *uav_heap;
18435     struct test_context_desc desc;
18436     struct test_context context;
18437     ID3D12CommandQueue *queue;
18438     ID3D12Device *device;
18439     unsigned int i;
18440     HRESULT hr;
18441 
18442     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
18443     static const DWORD ps_ld_texture_code[] =
18444     {
18445 #if 0
18446         RWTexture2D<float> u;
18447 
18448         float4 main(float4 position : SV_Position) : SV_Target
18449         {
18450             float2 s;
18451             u.GetDimensions(s.x, s.y);
18452             return u[s * float2(position.x / 640.0f, position.y / 480.0f)];
18453         }
18454 #endif
18455         0x43425844, 0x85c096ab, 0x210d7572, 0xdb1951af, 0x4dadced7, 0x00000001, 0x00000194, 0x00000003,
18456         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
18457         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
18458         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
18459         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000f8, 0x00000050,
18460         0x0000003e, 0x0100086a, 0x0400189c, 0x0011e000, 0x00000001, 0x00005555, 0x04002064, 0x00101032,
18461         0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x8900003d,
18462         0x800000c2, 0x00155543, 0x00100032, 0x00000000, 0x00004001, 0x00000000, 0x0011ee46, 0x00000001,
18463         0x07000038, 0x001000f2, 0x00000000, 0x00100546, 0x00000000, 0x00101546, 0x00000000, 0x0a000038,
18464         0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x3b088889,
18465         0x3b088889, 0x0500001c, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x890000a3, 0x800000c2,
18466         0x00155543, 0x00100012, 0x00000000, 0x00100e46, 0x00000000, 0x0011ee46, 0x00000001, 0x05000036,
18467         0x001020f2, 0x00000000, 0x00100006, 0x00000000, 0x0100003e,
18468     };
18469     static const D3D12_SHADER_BYTECODE ps_ld_texture = {ps_ld_texture_code, sizeof(ps_ld_texture_code)};
18470     static const DWORD ps_ld_buffer_code[] =
18471     {
18472 #if 0
18473         RWByteAddressBuffer u;
18474 
18475         uint location;
18476 
18477         float4 main(float4 position : SV_Position) : SV_Target
18478         {
18479             return u.Load(4 * location);
18480         }
18481 #endif
18482         0x43425844, 0xde636789, 0x7bc99233, 0x8b0609b6, 0x4b9a958e, 0x00000001, 0x00000134, 0x00000003,
18483         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
18484         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69,
18485         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
18486         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000098, 0x00000050,
18487         0x00000026, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300009d, 0x0011e000,
18488         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x08000029, 0x00100012,
18489         0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x00004001, 0x00000002, 0x890000a5, 0x800002c2,
18490         0x00199983, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0011e006, 0x00000001, 0x05000056,
18491         0x001020f2, 0x00000000, 0x00100006, 0x00000000, 0x0100003e,
18492     };
18493     static const D3D12_SHADER_BYTECODE ps_ld_buffer = {ps_ld_buffer_code, sizeof(ps_ld_buffer_code)};
18494     static const struct test
18495     {
18496         const D3D12_SHADER_BYTECODE *ps;
18497         D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
18498         uint32_t location;
18499     }
18500     tests[] =
18501     {
18502         {&ps_ld_texture, {DXGI_FORMAT_R32_UINT, D3D12_UAV_DIMENSION_TEXTURE2D}, 0},
18503         {&ps_ld_buffer,
18504                 {DXGI_FORMAT_R32_TYPELESS, D3D12_UAV_DIMENSION_BUFFER, .Buffer = {0, 1024, .Flags = D3D12_BUFFER_UAV_FLAG_RAW}},
18505                 0},
18506         {&ps_ld_buffer,
18507                 {DXGI_FORMAT_R32_TYPELESS, D3D12_UAV_DIMENSION_BUFFER, .Buffer = {0, 1024, .Flags = D3D12_BUFFER_UAV_FLAG_RAW}},
18508                 1024},
18509     };
18510 
18511     memset(&desc, 0, sizeof(desc));
18512     desc.no_root_signature = true;
18513     if (!init_test_context(&context, &desc))
18514         return;
18515     device = context.device;
18516     command_list = context.list;
18517     queue = context.queue;
18518 
18519     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
18520     descriptor_ranges[0].NumDescriptors = 1;
18521     descriptor_ranges[0].BaseShaderRegister = 1;
18522     descriptor_ranges[0].RegisterSpace = 0;
18523     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
18524     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
18525     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
18526     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
18527     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
18528     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
18529     root_parameters[1].Constants.ShaderRegister = 0;
18530     root_parameters[1].Constants.RegisterSpace = 0;
18531     root_parameters[1].Constants.Num32BitValues = 1;
18532     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
18533     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
18534     root_signature_desc.pParameters = root_parameters;
18535     root_signature_desc.NumStaticSamplers = 0;
18536     root_signature_desc.pStaticSamplers = NULL;
18537     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
18538     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
18539     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
18540 
18541     uav_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
18542 
18543     current_ps = NULL;
18544     for (i = 0; i < ARRAY_SIZE(tests); ++i)
18545     {
18546         const struct test *test = &tests[i];
18547 
18548         vkd3d_test_set_context("Test %u", i);
18549 
18550         if (current_ps != test->ps)
18551         {
18552             if (context.pipeline_state)
18553                 ID3D12PipelineState_Release(context.pipeline_state);
18554             current_ps = tests[i].ps;
18555             context.pipeline_state = create_pipeline_state(context.device,
18556                     context.root_signature, context.render_target_desc.Format, NULL, current_ps, NULL);
18557         }
18558 
18559         cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(uav_heap);
18560         ID3D12Device_CreateUnorderedAccessView(device, NULL, NULL, &test->uav_desc, cpu_handle);
18561 
18562         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
18563         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
18564         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
18565         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
18566         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &uav_heap);
18567         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
18568                 ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(uav_heap));
18569         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(command_list, 1, test->location, 0);
18570         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
18571         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
18572         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
18573         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
18574 
18575         transition_sub_resource_state(command_list, context.render_target, 0,
18576                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
18577         check_sub_resource_uint(context.render_target, 0, queue, command_list, 0x00000000, 0);
18578 
18579         reset_command_list(command_list, context.allocator);
18580         transition_sub_resource_state(command_list, context.render_target, 0,
18581                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
18582     }
18583     vkd3d_test_set_context(NULL);
18584 
18585     ID3D12DescriptorHeap_Release(uav_heap);
18586     destroy_test_context(&context);
18587 }
18588 
test_null_vbv(void)18589 static void test_null_vbv(void)
18590 {
18591     ID3D12GraphicsCommandList *command_list;
18592     D3D12_INPUT_LAYOUT_DESC input_layout;
18593     D3D12_VERTEX_BUFFER_VIEW vbv[2];
18594     struct test_context_desc desc;
18595     struct test_context context;
18596     ID3D12CommandQueue *queue;
18597     ID3D12Resource *vb;
18598 
18599     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
18600     {
18601         {"SV_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT,
18602                 D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
18603         {"COLOR",       0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT,
18604                 D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
18605     };
18606     static const DWORD vs_code[] =
18607     {
18608 #if 0
18609         struct vs_data
18610         {
18611             float4 pos : SV_POSITION;
18612             float4 color : COLOR;
18613         };
18614 
18615         void main(in struct vs_data vs_input, out struct vs_data vs_output)
18616         {
18617             vs_output.pos = vs_input.pos;
18618             vs_output.color = vs_input.color;
18619         }
18620 #endif
18621         0x43425844, 0xd5b32785, 0x35332906, 0x4d05e031, 0xf66a58af, 0x00000001, 0x00000144, 0x00000003,
18622         0x0000002c, 0x00000080, 0x000000d4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
18623         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000044, 0x00000000, 0x00000000,
18624         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
18625         0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003,
18626         0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
18627         0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x52444853, 0x00000068, 0x00010040,
18628         0x0000001a, 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x001010f2, 0x00000001, 0x04000067,
18629         0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x001020f2,
18630         0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x001020f2, 0x00000001, 0x00101e46, 0x00000001,
18631         0x0100003e,
18632     };
18633     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
18634     static const DWORD ps_code[] =
18635     {
18636 #if 0
18637         struct ps_data
18638         {
18639             float4 pos : SV_POSITION;
18640             float4 color : COLOR;
18641         };
18642 
18643         float4 main(struct ps_data ps_input) : SV_Target
18644         {
18645             return ps_input.color;
18646         }
18647 #endif
18648         0x43425844, 0x89803e59, 0x3f798934, 0xf99181df, 0xf5556512, 0x00000001, 0x000000f4, 0x00000003,
18649         0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
18650         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000,
18651         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
18652         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
18653         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000038, 0x00000040,
18654         0x0000000e, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x05000036,
18655         0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e,
18656     };
18657     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
18658     static const struct vec4 positions[] =
18659     {
18660         {-1.0f, -1.0f, 0.0f, 1.0f},
18661         {-1.0f,  1.0f, 0.0f, 1.0f},
18662         { 1.0f, -1.0f, 0.0f, 1.0f},
18663         { 1.0f,  1.0f, 0.0f, 1.0f},
18664     };
18665     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
18666 
18667     memset(&desc, 0, sizeof(desc));
18668     desc.no_root_signature = true;
18669     if (!init_test_context(&context, &desc))
18670         return;
18671     command_list = context.list;
18672     queue = context.queue;
18673 
18674     context.root_signature = create_empty_root_signature(context.device,
18675             D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
18676     input_layout.pInputElementDescs = layout_desc;
18677     input_layout.NumElements = ARRAY_SIZE(layout_desc);
18678     context.pipeline_state = create_pipeline_state(context.device,
18679             context.root_signature, context.render_target_desc.Format, &vs, &ps, &input_layout);
18680 
18681     vb = create_upload_buffer(context.device, sizeof(positions), positions);
18682 
18683     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
18684 
18685     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
18686     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
18687     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
18688     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
18689     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
18690     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
18691 
18692     vbv[0].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
18693     vbv[0].StrideInBytes = sizeof(*positions);
18694     vbv[0].SizeInBytes = sizeof(positions);
18695     vbv[1] = vbv[0];
18696     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
18697     vbv[1].BufferLocation = 0;
18698     vbv[1].StrideInBytes = 0;
18699     vbv[1].SizeInBytes = 0;
18700     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
18701 
18702     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 4, 0, 0);
18703 
18704     transition_resource_state(command_list, context.render_target,
18705             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
18706     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0x00000000, 0);
18707 
18708     ID3D12Resource_Release(vb);
18709     destroy_test_context(&context);
18710 }
18711 
18712 #define check_copyable_footprints(a, b, c, d, e, f, g, h) \
18713         check_copyable_footprints_(__LINE__, a, b, c, d, e, f, g, h)
check_copyable_footprints_(unsigned int line,const D3D12_RESOURCE_DESC * desc,unsigned int sub_resource_idx,unsigned int sub_resource_count,uint64_t base_offset,const D3D12_PLACED_SUBRESOURCE_FOOTPRINT * layouts,const UINT * row_counts,const uint64_t * row_sizes,uint64_t * total_size)18714 static void check_copyable_footprints_(unsigned int line, const D3D12_RESOURCE_DESC *desc,
18715         unsigned int sub_resource_idx, unsigned int sub_resource_count, uint64_t base_offset,
18716         const D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts, const UINT *row_counts,
18717         const uint64_t *row_sizes, uint64_t *total_size)
18718 {
18719     unsigned int miplevel, width, height, depth, row_count, row_size, row_pitch;
18720     uint64_t offset, size, total;
18721     unsigned int i;
18722 
18723     offset = total = 0;
18724     for (i = 0; i < sub_resource_count; ++i)
18725     {
18726         miplevel = (sub_resource_idx + i) % desc->MipLevels;
18727         width = align(max(1, desc->Width >> miplevel), format_block_width(desc->Format));
18728         height = align(max(1, desc->Height >> miplevel), format_block_height(desc->Format));
18729         depth = desc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? desc->DepthOrArraySize : 1;
18730         depth = max(1, depth >> miplevel);
18731         row_count = height / format_block_height(desc->Format);
18732         row_size = (width / format_block_width(desc->Format)) * format_size(desc->Format);
18733         row_pitch = align(row_size, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
18734 
18735         if (layouts)
18736         {
18737             const D3D12_PLACED_SUBRESOURCE_FOOTPRINT *l = &layouts[i];
18738             const D3D12_SUBRESOURCE_FOOTPRINT *f = &l->Footprint;
18739 
18740             ok_(line)(l->Offset == base_offset + offset,
18741                     "Got offset %"PRIu64", expected %"PRIu64".\n", l->Offset, base_offset + offset);
18742             ok_(line)(f->Format == desc->Format, "Got format %#x, expected %#x.\n", f->Format, desc->Format);
18743             ok_(line)(f->Width == width, "Got width %u, expected %u.\n", f->Width, width);
18744             ok_(line)(f->Height == height, "Got height %u, expected %u.\n", f->Height, height);
18745             ok_(line)(f->Depth == depth, "Got depth %u, expected %u.\n", f->Depth, depth);
18746             ok_(line)(f->RowPitch == row_pitch, "Got row pitch %u, expected %u.\n", f->RowPitch, row_pitch);
18747         }
18748 
18749         if (row_counts)
18750             ok_(line)(row_counts[i] == row_count, "Got row count %u, expected %u.\n", row_counts[i], row_count);
18751 
18752         if (row_sizes)
18753             ok_(line)(row_sizes[i] == row_size, "Got row size %"PRIu64", expected %u.\n", row_sizes[i], row_size);
18754 
18755         size = max(0, row_count - 1) * row_pitch + row_size;
18756         size = max(0, depth - 1) * align(size, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) + size;
18757 
18758         total = offset + size;
18759         offset = align(total, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
18760     }
18761 
18762     if (total_size)
18763         ok_(line)(*total_size == total, "Got total size %"PRIu64", expected %"PRIu64".\n", *total_size, total);
18764 }
18765 
test_get_copyable_footprints(void)18766 static void test_get_copyable_footprints(void)
18767 {
18768     D3D12_PLACED_SUBRESOURCE_FOOTPRINT layouts[10];
18769     uint64_t row_sizes[10], total_size;
18770     D3D12_RESOURCE_DESC resource_desc;
18771     unsigned int sub_resource_count;
18772     unsigned int i, j, k, l;
18773     ID3D12Device *device;
18774     UINT row_counts[10];
18775     ULONG refcount;
18776 
18777     static const struct
18778     {
18779         D3D12_RESOURCE_DIMENSION dimension;
18780         unsigned int width;
18781         unsigned int height;
18782         unsigned int depth_or_array_size;
18783         unsigned int miplevel_count;
18784         bool test_with_compressed;
18785     }
18786     resources[] =
18787     {
18788         {D3D12_RESOURCE_DIMENSION_BUFFER, 4, 1, 1, 1, false},
18789         {D3D12_RESOURCE_DIMENSION_TEXTURE1D, 4, 1, 1, 1, false},
18790         {D3D12_RESOURCE_DIMENSION_TEXTURE1D, 4, 1, 1, 2, false},
18791         {D3D12_RESOURCE_DIMENSION_TEXTURE1D, 3, 1, 1, 1, false},
18792         {D3D12_RESOURCE_DIMENSION_TEXTURE1D, 4, 1, 2, 1, false},
18793         {D3D12_RESOURCE_DIMENSION_TEXTURE2D, 4, 4, 1, 1, true},
18794         {D3D12_RESOURCE_DIMENSION_TEXTURE2D, 4, 4, 2, 1, true},
18795         {D3D12_RESOURCE_DIMENSION_TEXTURE2D, 4, 4, 1, 2, true},
18796         {D3D12_RESOURCE_DIMENSION_TEXTURE2D, 3, 1, 1, 2, false},
18797         {D3D12_RESOURCE_DIMENSION_TEXTURE2D, 3, 2, 1, 2, false},
18798         {D3D12_RESOURCE_DIMENSION_TEXTURE2D, 3, 1, 1, 1, false},
18799         {D3D12_RESOURCE_DIMENSION_TEXTURE2D, 3, 2, 1, 1, false},
18800         {D3D12_RESOURCE_DIMENSION_TEXTURE3D, 4, 4, 1, 1, true},
18801         {D3D12_RESOURCE_DIMENSION_TEXTURE3D, 4, 4, 2, 1, true},
18802         {D3D12_RESOURCE_DIMENSION_TEXTURE3D, 4, 4, 2, 2, true},
18803         {D3D12_RESOURCE_DIMENSION_TEXTURE3D, 8, 8, 8, 4, true},
18804         {D3D12_RESOURCE_DIMENSION_TEXTURE3D, 3, 2, 2, 2, false},
18805     };
18806     static const struct
18807     {
18808         DXGI_FORMAT format;
18809         bool is_compressed;
18810     }
18811     formats[] =
18812     {
18813         {DXGI_FORMAT_R32G32B32A32_FLOAT, false},
18814         {DXGI_FORMAT_R32G32B32A32_UINT, false},
18815         {DXGI_FORMAT_R32_UINT, false},
18816         {DXGI_FORMAT_R8G8B8A8_UNORM, false},
18817         {DXGI_FORMAT_BC1_UNORM, true},
18818         {DXGI_FORMAT_BC2_UNORM, true},
18819         {DXGI_FORMAT_BC3_UNORM, true},
18820         {DXGI_FORMAT_BC4_UNORM, true},
18821         {DXGI_FORMAT_BC5_UNORM, true},
18822         {DXGI_FORMAT_BC6H_UF16, true},
18823         {DXGI_FORMAT_BC6H_SF16, true},
18824         {DXGI_FORMAT_BC7_UNORM, true},
18825     };
18826     static const uint64_t base_offsets[] =
18827     {
18828         0, 1, 2, 30, 255, 512, 513, 600, 4096, 4194304, ~(uint64_t)0,
18829     };
18830     static const struct
18831     {
18832         D3D12_RESOURCE_DESC resource_desc;
18833         unsigned int sub_resource_idx;
18834         unsigned int sub_resource_count;
18835     }
18836     invalid_descs[] =
18837     {
18838         {
18839             {D3D12_RESOURCE_DIMENSION_BUFFER, 0, 3, 2, 1, 1, DXGI_FORMAT_R32_UINT,
18840                 {1, 0}, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_NONE}, 0, 1,
18841         },
18842         {
18843             {D3D12_RESOURCE_DIMENSION_TEXTURE1D, 0, 4, 2, 1, 1, DXGI_FORMAT_R32_UINT,
18844                 {1, 0}, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_NONE}, 0, 1,
18845         },
18846         {
18847             {D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, 4, 4, 1, 1, DXGI_FORMAT_R32_UINT,
18848                 {1, 0}, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_NONE}, 0, 2,
18849         },
18850         {
18851             {D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, 3, 1, 1, 2, DXGI_FORMAT_BC1_UNORM,
18852                 {1, 0}, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_NONE}, 0, 2,
18853         },
18854         {
18855             {D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, 3, 1, 1, 1, DXGI_FORMAT_BC1_UNORM,
18856                 {1, 0}, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_NONE}, 0, 1,
18857         },
18858         {
18859             {D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, 3, 1, 1, 2, DXGI_FORMAT_BC7_UNORM,
18860                 {1, 0}, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_NONE}, 0, 2,
18861         },
18862         {
18863             {D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, 3, 1, 1, 1, DXGI_FORMAT_BC7_UNORM,
18864                 {1, 0}, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_NONE}, 0, 1,
18865         },
18866         {
18867             {D3D12_RESOURCE_DIMENSION_TEXTURE3D, 3, 2, 2, 2, 2, DXGI_FORMAT_BC1_UNORM,
18868                 {1, 0}, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_NONE}, 0, 1,
18869         },
18870     };
18871 
18872     if (!(device = create_device()))
18873     {
18874         skip("Failed to create device.\n");
18875         return;
18876     }
18877 
18878     for (i = 0; i < ARRAY_SIZE(resources); ++i)
18879     {
18880         const bool is_buffer = resources[i].dimension == D3D12_RESOURCE_DIMENSION_BUFFER;
18881 
18882         resource_desc.Dimension = resources[i].dimension;
18883         resource_desc.Alignment = 0;
18884         resource_desc.Width = resources[i].width;
18885         resource_desc.Height = resources[i].height;
18886         resource_desc.DepthOrArraySize = resources[i].depth_or_array_size;
18887         resource_desc.MipLevels = resources[i].miplevel_count;
18888 
18889         for (j = 0; j < ARRAY_SIZE(formats); ++j)
18890         {
18891             if (formats[j].is_compressed && !resources[i].test_with_compressed)
18892                 continue;
18893             if (is_buffer && j > 0)
18894                 continue;
18895 
18896             if (is_buffer)
18897                 resource_desc.Format = DXGI_FORMAT_UNKNOWN;
18898             else
18899                 resource_desc.Format = formats[j].format;
18900 
18901             resource_desc.SampleDesc.Count = 1;
18902             resource_desc.SampleDesc.Quality = 0;
18903             resource_desc.Layout = is_buffer ? D3D12_TEXTURE_LAYOUT_ROW_MAJOR : D3D12_TEXTURE_LAYOUT_UNKNOWN;
18904             resource_desc.Flags = D3D12_RESOURCE_FLAG_NONE;
18905 
18906             sub_resource_count = resource_desc.MipLevels;
18907             if (resources[i].dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D)
18908                 sub_resource_count *= resource_desc.DepthOrArraySize;
18909             assert(sub_resource_count <= ARRAY_SIZE(layouts));
18910 
18911             for (k = 0; k < ARRAY_SIZE(base_offsets); ++k)
18912             {
18913                 vkd3d_test_set_context("resource %u, format %#x, offset %#"PRIx64,
18914                         i, resource_desc.Format, base_offsets[k]);
18915 
18916                 memset(layouts, 0, sizeof(layouts));
18917                 memset(row_counts, 0, sizeof(row_counts));
18918                 memset(row_sizes, 0, sizeof(row_sizes));
18919                 total_size = 0;
18920                 ID3D12Device_GetCopyableFootprints(device, &resource_desc, 0, sub_resource_count, base_offsets[k],
18921                         layouts, row_counts, row_sizes, &total_size);
18922                 check_copyable_footprints(&resource_desc, 0, sub_resource_count, base_offsets[k],
18923                         layouts, row_counts, row_sizes, &total_size);
18924 
18925                 memset(layouts, 0, sizeof(layouts));
18926                 ID3D12Device_GetCopyableFootprints(device, &resource_desc, 0, sub_resource_count, base_offsets[k],
18927                         layouts, NULL, NULL, NULL);
18928                 check_copyable_footprints(&resource_desc, 0, sub_resource_count, base_offsets[k],
18929                         layouts, NULL, NULL, NULL);
18930                 memset(row_counts, 0, sizeof(row_counts));
18931                 ID3D12Device_GetCopyableFootprints(device, &resource_desc, 0, sub_resource_count, base_offsets[k],
18932                         NULL, row_counts, NULL, NULL);
18933                 check_copyable_footprints(&resource_desc, 0, sub_resource_count, base_offsets[k],
18934                         NULL, row_counts, NULL, NULL);
18935                 memset(row_sizes, 0, sizeof(row_sizes));
18936                 ID3D12Device_GetCopyableFootprints(device, &resource_desc, 0, sub_resource_count, base_offsets[k],
18937                         NULL, NULL, row_sizes, NULL);
18938                 check_copyable_footprints(&resource_desc, 0, sub_resource_count, base_offsets[k],
18939                         NULL, NULL, row_sizes, NULL);
18940                 total_size = 0;
18941                 ID3D12Device_GetCopyableFootprints(device, &resource_desc, 0, sub_resource_count, base_offsets[k],
18942                         NULL, NULL, NULL, &total_size);
18943                 check_copyable_footprints(&resource_desc, 0, sub_resource_count, base_offsets[k],
18944                         NULL, NULL, NULL, &total_size);
18945 
18946                 for (l = 0; l < sub_resource_count; ++l)
18947                 {
18948                     vkd3d_test_set_context("resource %u, format %#x, offset %#"PRIx64", sub-resource %u",
18949                             i, resource_desc.Format, base_offsets[k], l);
18950 
18951                     memset(layouts, 0, sizeof(layouts));
18952                     memset(row_counts, 0, sizeof(row_counts));
18953                     memset(row_sizes, 0, sizeof(row_sizes));
18954                     total_size = 0;
18955                     ID3D12Device_GetCopyableFootprints(device, &resource_desc, l, 1, base_offsets[k],
18956                             layouts, row_counts, row_sizes, &total_size);
18957                     check_copyable_footprints(&resource_desc, l, 1, base_offsets[k],
18958                             layouts, row_counts, row_sizes, &total_size);
18959                 }
18960             }
18961         }
18962     }
18963     vkd3d_test_set_context(NULL);
18964 
18965     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
18966     resource_desc.Alignment = 0;
18967     resource_desc.Width = 512;
18968     resource_desc.Height = 512;
18969     resource_desc.DepthOrArraySize = 1;
18970     resource_desc.MipLevels = 1;
18971     resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
18972     resource_desc.SampleDesc.Count = 4;
18973     resource_desc.SampleDesc.Quality = 0;
18974     resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
18975     memset(layouts, 0, sizeof(layouts));
18976     memset(row_counts, 0, sizeof(row_counts));
18977     memset(row_sizes, 0, sizeof(row_sizes));
18978     total_size = 0;
18979     ID3D12Device_GetCopyableFootprints(device, &resource_desc, 0, 1, 0,
18980             layouts, row_counts, row_sizes, &total_size);
18981     check_copyable_footprints(&resource_desc, 0, 1, 0,
18982             layouts, row_counts, row_sizes, &total_size);
18983 
18984     for (i = 0; i < ARRAY_SIZE(invalid_descs); ++i)
18985     {
18986         resource_desc = invalid_descs[i].resource_desc;
18987 
18988         memset(layouts, 0, sizeof(layouts));
18989         memset(row_counts, 0, sizeof(row_counts));
18990         memset(row_sizes, 0, sizeof(row_sizes));
18991         total_size = 0;
18992         ID3D12Device_GetCopyableFootprints(device, &resource_desc,
18993                 invalid_descs[i].sub_resource_idx, invalid_descs[i].sub_resource_count, 0,
18994                 layouts, row_counts, row_sizes, &total_size);
18995 
18996         for (j = 0; j < invalid_descs[i].sub_resource_count; ++j)
18997         {
18998             const D3D12_PLACED_SUBRESOURCE_FOOTPRINT *l = &layouts[j];
18999 
19000             ok(l->Offset == ~(uint64_t)0, "Got offset %"PRIu64".\n", l->Offset);
19001             ok(l->Footprint.Format == ~(DXGI_FORMAT)0, "Got format %#x.\n", l->Footprint.Format);
19002             ok(l->Footprint.Width == ~0u, "Got width %u.\n", l->Footprint.Width);
19003             ok(l->Footprint.Height == ~0u, "Got height %u.\n", l->Footprint.Height);
19004             ok(l->Footprint.Depth == ~0u, "Got depth %u.\n", l->Footprint.Depth);
19005             ok(l->Footprint.RowPitch == ~0u, "Got row pitch %u.\n", l->Footprint.RowPitch);
19006 
19007             ok(row_counts[j] == ~0u, "Got row count %u.\n", row_counts[j]);
19008             ok(row_sizes[j] == ~(uint64_t)0, "Got row size %"PRIu64".\n", row_sizes[j]);
19009         }
19010 
19011         ok(total_size == ~(uint64_t)0, "Got total size %"PRIu64".\n", total_size);
19012     }
19013 
19014     refcount = ID3D12Device_Release(device);
19015     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
19016 }
19017 
test_depth_clip(void)19018 static void test_depth_clip(void)
19019 {
19020     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
19021     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
19022     ID3D12GraphicsCommandList *command_list;
19023     D3D12_INPUT_LAYOUT_DESC input_layout;
19024     struct depth_stencil_resource ds;
19025     struct test_context_desc desc;
19026     D3D12_VERTEX_BUFFER_VIEW vbv;
19027     struct test_context context;
19028     ID3D12CommandQueue *queue;
19029     ID3D12Resource *vb;
19030     unsigned int i;
19031     float depth;
19032     HRESULT hr;
19033 
19034     static const DWORD vs_code[] =
19035     {
19036 #if 0
19037         float4 main(float4 p : POSITION) : SV_Position
19038         {
19039             return p;
19040         }
19041 #endif
19042         0x43425844, 0x92767590, 0x06a6dba7, 0x0ae078b2, 0x7b5eb8f6, 0x00000001, 0x000000d8, 0x00000003,
19043         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
19044         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
19045         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
19046         0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x52444853, 0x0000003c, 0x00010040,
19047         0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
19048         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
19049     };
19050     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
19051     static const DWORD ps_depth_code[] =
19052     {
19053 #if 0
19054         float depth;
19055 
19056         float4 main(float4 p : SV_Position, out float out_depth : SV_Depth) : SV_Target
19057         {
19058             out_depth = depth;
19059             return float4(0, 1, 0, 1);
19060         }
19061 #endif
19062         0x43425844, 0x6744db20, 0x3e266cd1, 0xc50630b3, 0xd7455b94, 0x00000001, 0x00000120, 0x00000003,
19063         0x0000002c, 0x00000060, 0x000000b4, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
19064         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69,
19065         0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000000, 0x00000003,
19066         0x00000000, 0x0000000f, 0x00000042, 0x00000000, 0x00000000, 0x00000003, 0xffffffff, 0x00000e01,
19067         0x545f5653, 0x65677261, 0x56530074, 0x7065445f, 0xab006874, 0x52444853, 0x00000064, 0x00000040,
19068         0x00000019, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
19069         0x02000065, 0x0000c001, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000, 0x3f800000,
19070         0x00000000, 0x3f800000, 0x05000036, 0x0000c001, 0x0020800a, 0x00000000, 0x00000000, 0x0100003e,
19071     };
19072     static const D3D12_SHADER_BYTECODE ps_depth = {ps_depth_code, sizeof(ps_depth_code)};
19073     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
19074     {
19075         {"position", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
19076     };
19077     static const struct vec4 vertices[] =
19078     {
19079         {-1.0f, -1.0f,  0.0f, 1.0f},
19080         {-1.0f,  1.0f,  0.0f, 1.0f},
19081         { 1.0f, -1.0f,  0.0f, 1.0f},
19082         { 1.0f,  1.0f,  0.0f, 1.0f},
19083 
19084         {-1.0f, -1.0f,  0.5f, 1.0f},
19085         {-1.0f,  1.0f,  0.5f, 1.0f},
19086         { 1.0f, -1.0f,  0.5f, 1.0f},
19087         { 1.0f,  1.0f,  0.5f, 1.0f},
19088 
19089         {-1.0f, -1.0f, -0.5f, 1.0f},
19090         {-1.0f,  1.0f, -0.5f, 1.0f},
19091         { 1.0f, -1.0f, -0.5f, 1.0f},
19092         { 1.0f,  1.0f, -0.5f, 1.0f},
19093 
19094         {-1.0f, -1.0f,  1.0f, 1.0f},
19095         {-1.0f,  1.0f,  1.0f, 1.0f},
19096         { 1.0f, -1.0f,  1.0f, 1.0f},
19097         { 1.0f,  1.0f,  1.0f, 1.0f},
19098 
19099         {-1.0f, -1.0f,  1.5f, 1.0f},
19100         {-1.0f,  1.0f,  1.5f, 1.0f},
19101         { 1.0f, -1.0f,  1.5f, 1.0f},
19102         { 1.0f,  1.0f,  1.5f, 1.0f},
19103     };
19104     struct result
19105     {
19106         uint32_t expected_color;
19107         float expected_depth;
19108     };
19109     static const struct
19110     {
19111         struct result depth_clip;
19112         struct result no_depth_clip;
19113     }
19114     tests[] =
19115     {
19116         {{0xff00ff00, 0.0f  }, {0xff00ff00, 0.0f}},
19117         {{0xff00ff00, 0.5f  }, {0xff00ff00, 0.5f}},
19118         {{0xffffffff, 0.125f}, {0xff00ff00, 0.0f}},
19119         {{0xff00ff00, 1.0f  }, {0xff00ff00, 1.0f}},
19120         {{0xffffffff, 0.125f}, {0xff00ff00, 1.0f}},
19121     };
19122 
19123     memset(&desc, 0, sizeof(desc));
19124     desc.no_root_signature = true;
19125     if (!init_test_context(&context, &desc))
19126         return;
19127     command_list = context.list;
19128     queue = context.queue;
19129 
19130     context.root_signature = create_32bit_constants_root_signature_(__LINE__, context.device,
19131             0, 4, D3D12_SHADER_VISIBILITY_PIXEL, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
19132 
19133     init_depth_stencil(&ds, context.device, 32, 32, 1, 1, DXGI_FORMAT_D32_FLOAT, 0, NULL);
19134 
19135     vb = create_upload_buffer(context.device, sizeof(vertices), vertices);
19136     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
19137     vbv.StrideInBytes = sizeof(*vertices);
19138     vbv.SizeInBytes = sizeof(vertices);
19139 
19140     input_layout.pInputElementDescs = layout_desc;
19141     input_layout.NumElements = ARRAY_SIZE(layout_desc);
19142     init_pipeline_state_desc(&pso_desc, context.root_signature,
19143             context.render_target_desc.Format, &vs, NULL, &input_layout);
19144     pso_desc.RasterizerState.DepthClipEnable = true;
19145     pso_desc.DepthStencilState.DepthEnable = true;
19146     pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
19147     pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
19148     pso_desc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
19149     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
19150             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
19151     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
19152 
19153     for (i = 0; i < ARRAY_SIZE(tests); ++i)
19154     {
19155         const struct result *result = &tests[i].depth_clip;
19156 
19157         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
19158         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list,
19159                 ds.dsv_handle, D3D12_CLEAR_FLAG_DEPTH, 0.125f, 0, 0, NULL);
19160 
19161         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, &ds.dsv_handle);
19162         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
19163         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
19164         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
19165         ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
19166         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
19167         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
19168         ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 4 * i, 0);
19169 
19170         transition_resource_state(command_list, ds.texture,
19171                 D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
19172         check_sub_resource_float(ds.texture, 0, queue, command_list, result->expected_depth, 2);
19173         reset_command_list(command_list, context.allocator);
19174 
19175         transition_resource_state(command_list, context.render_target,
19176                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
19177         check_sub_resource_uint(context.render_target, 0, queue, command_list, result->expected_color, 0);
19178 
19179         reset_command_list(command_list, context.allocator);
19180         transition_resource_state(command_list, ds.texture,
19181                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE);
19182         transition_resource_state(command_list, context.render_target,
19183                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
19184     }
19185 
19186     ID3D12PipelineState_Release(context.pipeline_state);
19187     pso_desc.RasterizerState.DepthClipEnable = false;
19188     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
19189             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
19190     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
19191 
19192     for (i = 0; i < ARRAY_SIZE(tests); ++i)
19193     {
19194         const struct result *result = &tests[i].no_depth_clip;
19195 
19196         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
19197         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list,
19198                 ds.dsv_handle, D3D12_CLEAR_FLAG_DEPTH, 0.125f, 0, 0, NULL);
19199 
19200         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, &ds.dsv_handle);
19201         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
19202         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
19203         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
19204         ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
19205         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
19206         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
19207         ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 4 * i, 0);
19208 
19209         transition_resource_state(command_list, ds.texture,
19210                 D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
19211         check_sub_resource_float(ds.texture, 0, queue, command_list, result->expected_depth, 2);
19212         reset_command_list(command_list, context.allocator);
19213 
19214         transition_resource_state(command_list, context.render_target,
19215                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
19216         check_sub_resource_uint(context.render_target, 0, queue, command_list, result->expected_color, 0);
19217 
19218         reset_command_list(command_list, context.allocator);
19219         transition_resource_state(command_list, ds.texture,
19220                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE);
19221         transition_resource_state(command_list, context.render_target,
19222                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
19223     }
19224 
19225     ID3D12PipelineState_Release(context.pipeline_state);
19226     pso_desc.PS = ps_depth;
19227     pso_desc.RasterizerState.DepthClipEnable = true;
19228     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
19229             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
19230     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
19231 
19232     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
19233     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list,
19234             ds.dsv_handle, D3D12_CLEAR_FLAG_DEPTH, 0.125f, 0, 0, NULL);
19235 
19236     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, &ds.dsv_handle);
19237     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
19238     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
19239     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
19240     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
19241     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
19242     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
19243     depth = 2.0f;
19244     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 1, &depth, 0);
19245     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
19246 
19247     transition_resource_state(command_list, ds.texture,
19248             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
19249     bug_if(!is_depth_clip_enable_supported(context.device))
19250     check_sub_resource_float(ds.texture, 0, queue, command_list, 1.0f, 2);
19251     reset_command_list(command_list, context.allocator);
19252 
19253     transition_resource_state(command_list, context.render_target,
19254             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
19255     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
19256 
19257     ID3D12Resource_Release(vb);
19258     destroy_depth_stencil(&ds);
19259     destroy_test_context(&context);
19260 }
19261 
19262 #define check_depth_stencil_sampling(a, b, c, d, e, f, g) \
19263         check_depth_stencil_sampling_(__LINE__, a, b, c, d, e, f, g)
check_depth_stencil_sampling_(unsigned int line,struct test_context * context,ID3D12PipelineState * pso,ID3D12Resource * cb,ID3D12Resource * texture,D3D12_CPU_DESCRIPTOR_HANDLE dsv_handle,ID3D12DescriptorHeap * srv_heap,float expected_value)19264 static void check_depth_stencil_sampling_(unsigned int line, struct test_context *context,
19265         ID3D12PipelineState *pso, ID3D12Resource *cb, ID3D12Resource *texture,
19266         D3D12_CPU_DESCRIPTOR_HANDLE dsv_handle, ID3D12DescriptorHeap *srv_heap,
19267         float expected_value)
19268 {
19269     static const float black[] = {0.0f, 0.0f, 0.0f, 0.0f};
19270     ID3D12GraphicsCommandList *command_list;
19271     ID3D12CommandQueue *queue;
19272     HRESULT hr;
19273 
19274     command_list = context->list;
19275     queue = context->queue;
19276 
19277     transition_sub_resource_state(command_list, texture, 0,
19278             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
19279 
19280     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context->rtv, black, 0, NULL);
19281     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context->rtv, false, NULL);
19282 
19283     ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
19284 
19285     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context->root_signature);
19286     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &srv_heap);
19287     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
19288             ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(srv_heap));
19289     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 1,
19290             ID3D12Resource_GetGPUVirtualAddress(cb));
19291     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
19292     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context->viewport);
19293     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context->scissor_rect);
19294     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
19295 
19296     transition_sub_resource_state(command_list, context->render_target, 0,
19297             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
19298     check_sub_resource_float_(line, context->render_target, 0, queue, command_list, expected_value, 2);
19299 
19300     reset_command_list(command_list, context->allocator);
19301     transition_sub_resource_state(command_list, context->render_target, 0,
19302             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
19303     transition_sub_resource_state(command_list, texture, 0,
19304             D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE);
19305     hr = ID3D12GraphicsCommandList_Close(command_list);
19306     ok_(line)(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
19307     exec_command_list(queue, command_list);
19308     wait_queue_idle(context->device, queue);
19309 }
19310 
test_depth_stencil_sampling(void)19311 static void test_depth_stencil_sampling(void)
19312 {
19313     ID3D12PipelineState *pso_compare, *pso_depth, *pso_stencil, *pso_depth_stencil;
19314     D3D12_CPU_DESCRIPTOR_HANDLE dsv_handle, srv_cpu_handle;
19315     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
19316     D3D12_STATIC_SAMPLER_DESC sampler_desc[2];
19317     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
19318     D3D12_DESCRIPTOR_RANGE descriptor_range;
19319     D3D12_ROOT_PARAMETER root_parameters[2];
19320     ID3D12GraphicsCommandList *command_list;
19321     struct depth_stencil_resource ds;
19322     ID3D12DescriptorHeap *srv_heap;
19323     struct test_context_desc desc;
19324     ID3D12Resource *cb, *texture;
19325     unsigned int descriptor_size;
19326     struct test_context context;
19327     struct vec4 ps_constant;
19328     ID3D12Device *device;
19329     unsigned int i;
19330     HRESULT hr;
19331 
19332     static const DWORD ps_compare_code[] =
19333     {
19334 #if 0
19335         Texture2D t;
19336         SamplerComparisonState s : register(s1);
19337 
19338         float ref;
19339 
19340         float4 main(float4 position : SV_Position) : SV_Target
19341         {
19342             return t.SampleCmp(s, float2(position.x / 640.0f, position.y / 480.0f), ref);
19343         }
19344 #endif
19345         0x43425844, 0xbea899fb, 0xcbeaa744, 0xbad6daa0, 0xd4363d30, 0x00000001, 0x00000164, 0x00000003,
19346         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
19347         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
19348         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
19349         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000c8, 0x00000040,
19350         0x00000032, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300085a, 0x00106000, 0x00000001,
19351         0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001,
19352         0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0a000038, 0x00100032, 0x00000000,
19353         0x00101046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x0c000046,
19354         0x00100012, 0x00000000, 0x00100046, 0x00000000, 0x00107006, 0x00000000, 0x00106000, 0x00000001,
19355         0x0020800a, 0x00000000, 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00100006, 0x00000000,
19356         0x0100003e,
19357     };
19358     static const D3D12_SHADER_BYTECODE ps_compare = {ps_compare_code, sizeof(ps_compare_code)};
19359     static const DWORD ps_sample_code[] =
19360     {
19361 #if 0
19362         Texture2D t;
19363         SamplerState s;
19364 
19365         float4 main(float4 position : SV_Position) : SV_Target
19366         {
19367             return t.Sample(s, float2(position.x / 640.0f, position.y / 480.0f));
19368         }
19369 #endif
19370         0x43425844, 0x7472c092, 0x5548f00e, 0xf4e007f1, 0x5970429c, 0x00000001, 0x00000134, 0x00000003,
19371         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
19372         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
19373         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
19374         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000098, 0x00000040,
19375         0x00000026, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555,
19376         0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
19377         0x00000001, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002, 0x3acccccd,
19378         0x3b088889, 0x00000000, 0x00000000, 0x09000045, 0x001020f2, 0x00000000, 0x00100046, 0x00000000,
19379         0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0100003e,
19380     };
19381     static const D3D12_SHADER_BYTECODE ps_sample = {ps_sample_code, sizeof(ps_sample_code)};
19382     static const DWORD ps_stencil_code[] =
19383     {
19384 #if 0
19385         Texture2D<uint4> t : register(t1);
19386 
19387         float4 main(float4 position : SV_Position) : SV_Target
19388         {
19389             float2 s;
19390             t.GetDimensions(s.x, s.y);
19391             return t.Load(int3(float3(s.x * position.x / 640.0f, s.y * position.y / 480.0f, 0))).y;
19392         }
19393 #endif
19394         0x43425844, 0x78574912, 0x1b7763f5, 0x0124de83, 0x39954d6c, 0x00000001, 0x000001a0, 0x00000003,
19395         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
19396         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
19397         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
19398         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000104, 0x00000040,
19399         0x00000041, 0x04001858, 0x00107000, 0x00000001, 0x00004444, 0x04002064, 0x00101032, 0x00000000,
19400         0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0700003d, 0x001000f2,
19401         0x00000000, 0x00004001, 0x00000000, 0x00107e46, 0x00000001, 0x07000038, 0x00100032, 0x00000000,
19402         0x00100046, 0x00000000, 0x00101046, 0x00000000, 0x0a000038, 0x00100032, 0x00000000, 0x00100046,
19403         0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x0500001b, 0x00100032,
19404         0x00000000, 0x00100046, 0x00000000, 0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000,
19405         0x00000000, 0x00000000, 0x00000000, 0x0700002d, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
19406         0x00107e46, 0x00000001, 0x05000056, 0x001020f2, 0x00000000, 0x00100556, 0x00000000, 0x0100003e,
19407     };
19408     static const D3D12_SHADER_BYTECODE ps_stencil = {ps_stencil_code, sizeof(ps_stencil_code)};
19409     static const DWORD ps_depth_stencil_code[] =
19410     {
19411 #if 0
19412         SamplerState samp;
19413         Texture2D depth_tex;
19414         Texture2D<uint4> stencil_tex;
19415 
19416         float main(float4 position: SV_Position) : SV_Target
19417         {
19418             float2 s, p;
19419             float depth, stencil;
19420             depth_tex.GetDimensions(s.x, s.y);
19421             p = float2(s.x * position.x / 640.0f, s.y * position.y / 480.0f);
19422             depth = depth_tex.Sample(samp, p).r;
19423             stencil = stencil_tex.Load(int3(float3(p.x, p.y, 0))).y;
19424             return depth + stencil;
19425         }
19426 #endif
19427         0x43425844, 0x348f8377, 0x977d1ee0, 0x8cca4f35, 0xff5c5afc, 0x00000001, 0x000001fc, 0x00000003,
19428         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
19429         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
19430         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
19431         0x00000000, 0x00000e01, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000160, 0x00000040,
19432         0x00000058, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555,
19433         0x04001858, 0x00107000, 0x00000001, 0x00004444, 0x04002064, 0x00101032, 0x00000000, 0x00000001,
19434         0x03000065, 0x00102012, 0x00000000, 0x02000068, 0x00000002, 0x0700003d, 0x001000f2, 0x00000000,
19435         0x00004001, 0x00000000, 0x00107e46, 0x00000000, 0x07000038, 0x00100032, 0x00000000, 0x00100046,
19436         0x00000000, 0x00101046, 0x00000000, 0x0a000038, 0x00100032, 0x00000000, 0x00100046, 0x00000000,
19437         0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x0500001b, 0x00100032, 0x00000001,
19438         0x00100046, 0x00000000, 0x09000045, 0x001000f2, 0x00000000, 0x00100046, 0x00000000, 0x00107e46,
19439         0x00000000, 0x00106000, 0x00000000, 0x08000036, 0x001000c2, 0x00000001, 0x00004002, 0x00000000,
19440         0x00000000, 0x00000000, 0x00000000, 0x0700002d, 0x001000f2, 0x00000001, 0x00100e46, 0x00000001,
19441         0x00107e46, 0x00000001, 0x05000056, 0x00100022, 0x00000000, 0x0010001a, 0x00000001, 0x07000000,
19442         0x00102012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e,
19443     };
19444     static const D3D12_SHADER_BYTECODE ps_depth_stencil = {ps_depth_stencil_code, sizeof(ps_depth_stencil_code)};
19445     static const struct test
19446     {
19447         DXGI_FORMAT typeless_format;
19448         DXGI_FORMAT dsv_format;
19449         DXGI_FORMAT depth_view_format;
19450         DXGI_FORMAT stencil_view_format;
19451     }
19452     tests[] =
19453     {
19454         {DXGI_FORMAT_R32G8X24_TYPELESS, DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
19455                 DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_X32_TYPELESS_G8X24_UINT},
19456         {DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_D32_FLOAT,
19457                 DXGI_FORMAT_R32_FLOAT},
19458         {DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT,
19459                 DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_X24_TYPELESS_G8_UINT},
19460         {DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_D16_UNORM,
19461                 DXGI_FORMAT_R16_UNORM},
19462     };
19463 
19464     memset(&desc, 0, sizeof(desc));
19465     desc.rt_width = 640;
19466     desc.rt_height = 480;
19467     desc.rt_format = DXGI_FORMAT_R32_FLOAT;
19468     desc.no_root_signature = true;
19469     if (!init_test_context(&context, &desc))
19470         return;
19471     device = context.device;
19472     command_list = context.list;
19473 
19474     sampler_desc[0].Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
19475     sampler_desc[0].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
19476     sampler_desc[0].AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
19477     sampler_desc[0].AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
19478     sampler_desc[0].MipLODBias = 0.0f;
19479     sampler_desc[0].MaxAnisotropy = 0;
19480     sampler_desc[0].ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
19481     sampler_desc[0].BorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE;
19482     sampler_desc[0].MinLOD = 0.0f;
19483     sampler_desc[0].MaxLOD = 0.0f;
19484     sampler_desc[0].ShaderRegister = 0;
19485     sampler_desc[0].RegisterSpace = 0;
19486     sampler_desc[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
19487 
19488     sampler_desc[1] = sampler_desc[0];
19489     sampler_desc[1].Filter = D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT;
19490     sampler_desc[1].ComparisonFunc = D3D12_COMPARISON_FUNC_GREATER;
19491     sampler_desc[1].ShaderRegister = 1;
19492 
19493     descriptor_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
19494     descriptor_range.NumDescriptors = 2;
19495     descriptor_range.BaseShaderRegister = 0;
19496     descriptor_range.RegisterSpace = 0;
19497     descriptor_range.OffsetInDescriptorsFromTableStart = 0;
19498     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
19499     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
19500     root_parameters[0].DescriptorTable.pDescriptorRanges = &descriptor_range;
19501     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
19502 
19503     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
19504     root_parameters[1].Descriptor.ShaderRegister = 0;
19505     root_parameters[1].Descriptor.RegisterSpace = 0;
19506     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
19507 
19508     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
19509     root_signature_desc.NumParameters = 2;
19510     root_signature_desc.pParameters = root_parameters;
19511     root_signature_desc.NumStaticSamplers = 2;
19512     root_signature_desc.pStaticSamplers = sampler_desc;
19513     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
19514     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
19515 
19516     pso_compare = create_pipeline_state(device,
19517             context.root_signature, context.render_target_desc.Format, NULL, &ps_compare, NULL);
19518     pso_depth = create_pipeline_state(device,
19519             context.root_signature, context.render_target_desc.Format, NULL, &ps_sample, NULL);
19520     pso_stencil = create_pipeline_state(device,
19521             context.root_signature, context.render_target_desc.Format, NULL, &ps_stencil, NULL);
19522     pso_depth_stencil = create_pipeline_state(device,
19523             context.root_signature, context.render_target_desc.Format, NULL, &ps_depth_stencil, NULL);
19524 
19525     srv_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
19526     descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(device,
19527             D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
19528 
19529     memset(&ps_constant, 0, sizeof(ps_constant));
19530     cb = create_upload_buffer(device, sizeof(ps_constant), &ps_constant);
19531 
19532     hr = ID3D12GraphicsCommandList_Close(command_list);
19533     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
19534 
19535     for (i = 0; i < ARRAY_SIZE(tests); ++i)
19536     {
19537         vkd3d_test_set_context("Test %u", i);
19538 
19539         reset_command_list(command_list, context.allocator);
19540 
19541         init_depth_stencil(&ds, device, context.render_target_desc.Width,
19542                 context.render_target_desc.Height, 1, 1, tests[i].typeless_format,
19543                 tests[i].dsv_format, NULL);
19544         texture = ds.texture;
19545         dsv_handle = ds.dsv_handle;
19546 
19547         srv_cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(srv_heap);
19548 
19549         memset(&srv_desc, 0, sizeof(srv_desc));
19550         srv_desc.Format = tests[i].depth_view_format;
19551         srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
19552         srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
19553         srv_desc.Texture2D.MipLevels = 1;
19554         ID3D12Device_CreateShaderResourceView(device, texture, &srv_desc, srv_cpu_handle);
19555         srv_cpu_handle.ptr += descriptor_size;
19556         ID3D12Device_CreateShaderResourceView(device, NULL, &srv_desc, srv_cpu_handle);
19557 
19558         ps_constant.x = 0.5f;
19559         update_buffer_data(cb, 0, sizeof(ps_constant), &ps_constant);
19560 
19561         /* pso_compare */
19562         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv_handle,
19563                 D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, NULL);
19564         check_depth_stencil_sampling(&context, pso_compare, cb, texture, dsv_handle, srv_heap, 0.0f);
19565 
19566         reset_command_list(command_list, context.allocator);
19567         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv_handle,
19568                 D3D12_CLEAR_FLAG_DEPTH, 0.0f, 0, 0, NULL);
19569         check_depth_stencil_sampling(&context, pso_compare, cb, texture, dsv_handle, srv_heap, 1.0f);
19570 
19571         reset_command_list(command_list, context.allocator);
19572         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv_handle,
19573                 D3D12_CLEAR_FLAG_DEPTH, 0.5f, 0, 0, NULL);
19574         check_depth_stencil_sampling(&context, pso_compare, cb, texture, dsv_handle, srv_heap, 0.0f);
19575 
19576         reset_command_list(command_list, context.allocator);
19577         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv_handle,
19578                 D3D12_CLEAR_FLAG_DEPTH, 0.6f, 0, 0, NULL);
19579         check_depth_stencil_sampling(&context, pso_compare, cb, texture, dsv_handle, srv_heap, 0.0f);
19580 
19581         ps_constant.x = 0.7f;
19582         update_buffer_data(cb, 0, sizeof(ps_constant), &ps_constant);
19583 
19584         reset_command_list(command_list, context.allocator);
19585         check_depth_stencil_sampling(&context, pso_compare, cb, texture, dsv_handle, srv_heap, 1.0f);
19586 
19587         /* pso_depth */
19588         reset_command_list(command_list, context.allocator);
19589         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv_handle,
19590                 D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, NULL);
19591         check_depth_stencil_sampling(&context, pso_depth, cb, texture, dsv_handle, srv_heap, 1.0f);
19592 
19593         reset_command_list(command_list, context.allocator);
19594         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv_handle,
19595                 D3D12_CLEAR_FLAG_DEPTH, 0.2f, 0, 0, NULL);
19596         check_depth_stencil_sampling(&context, pso_depth, cb, texture, dsv_handle, srv_heap, 0.2f);
19597 
19598         if (!tests[i].stencil_view_format)
19599         {
19600             destroy_depth_stencil(&ds);
19601             continue;
19602         }
19603         if (is_amd_windows_device(device))
19604         {
19605             skip("Reads from depth/stencil shader resource views return stale values on some AMD drivers.\n");
19606             destroy_depth_stencil(&ds);
19607             continue;
19608         }
19609 
19610         srv_desc.Format = tests[i].stencil_view_format;
19611         srv_desc.Texture2D.PlaneSlice = 1;
19612         ID3D12Device_CreateShaderResourceView(device, texture, &srv_desc, srv_cpu_handle);
19613 
19614         /* pso_stencil */
19615         reset_command_list(command_list, context.allocator);
19616         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv_handle,
19617                 D3D12_CLEAR_FLAG_STENCIL, 0.0f, 0, 0, NULL);
19618         check_depth_stencil_sampling(&context, pso_stencil, cb, texture, dsv_handle, srv_heap, 0.0f);
19619 
19620         reset_command_list(command_list, context.allocator);
19621         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv_handle,
19622                 D3D12_CLEAR_FLAG_STENCIL, 0.0f, 100, 0, NULL);
19623         check_depth_stencil_sampling(&context, pso_stencil, cb, texture, dsv_handle, srv_heap, 100.0f);
19624 
19625         reset_command_list(command_list, context.allocator);
19626         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv_handle,
19627                 D3D12_CLEAR_FLAG_STENCIL, 0.0f, 255, 0, NULL);
19628         check_depth_stencil_sampling(&context, pso_stencil, cb, texture, dsv_handle, srv_heap, 255.0f);
19629 
19630         /* pso_depth_stencil */
19631         reset_command_list(command_list, context.allocator);
19632         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv_handle,
19633                 D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 0.3f, 3, 0, NULL);
19634         check_depth_stencil_sampling(&context, pso_depth_stencil, cb, texture, dsv_handle, srv_heap, 3.3f);
19635 
19636         reset_command_list(command_list, context.allocator);
19637         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv_handle,
19638                 D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 1.0f, 3, 0, NULL);
19639         check_depth_stencil_sampling(&context, pso_depth_stencil, cb, texture, dsv_handle, srv_heap, 4.0f);
19640 
19641         reset_command_list(command_list, context.allocator);
19642         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, dsv_handle,
19643                 D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 0.0f, 0, 0, NULL);
19644         check_depth_stencil_sampling(&context, pso_depth_stencil, cb, texture, dsv_handle, srv_heap, 0.0f);
19645 
19646         destroy_depth_stencil(&ds);
19647     }
19648     vkd3d_test_set_context(NULL);
19649 
19650     ID3D12Resource_Release(cb);
19651     ID3D12DescriptorHeap_Release(srv_heap);
19652     ID3D12PipelineState_Release(pso_compare);
19653     ID3D12PipelineState_Release(pso_depth);
19654     ID3D12PipelineState_Release(pso_stencil);
19655     ID3D12PipelineState_Release(pso_depth_stencil);
19656     destroy_test_context(&context);
19657 }
19658 
test_depth_load(void)19659 static void test_depth_load(void)
19660 {
19661     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
19662     D3D12_DESCRIPTOR_RANGE descriptor_ranges[2];
19663     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
19664     D3D12_ROOT_PARAMETER root_parameters[1];
19665     ID3D12GraphicsCommandList *command_list;
19666     ID3D12PipelineState *pipeline_state;
19667     struct depth_stencil_resource ds;
19668     struct test_context_desc desc;
19669     struct test_context context;
19670     ID3D12DescriptorHeap *heap;
19671     ID3D12CommandQueue *queue;
19672     ID3D12Resource *texture;
19673     ID3D12Device *device;
19674     unsigned int i;
19675     HRESULT hr;
19676 
19677     static const DWORD cs_code[] =
19678     {
19679 #if 0
19680         Texture2D<float> t;
19681         RWTexture2D<float> u;
19682 
19683         [numthreads(1, 1, 1)]
19684         void main(uint2 id : SV_GroupID)
19685         {
19686             u[id] = t[id];
19687         }
19688 #endif
19689         0x43425844, 0x6ddce3d0, 0x24b47ad3, 0x7f6772d2, 0x6a644890, 0x00000001, 0x00000110, 0x00000003,
19690         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
19691         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000bc, 0x00050050, 0x0000002f, 0x0100086a,
19692         0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x0400189c, 0x0011e000, 0x00000000, 0x00005555,
19693         0x0200005f, 0x00021032, 0x02000068, 0x00000001, 0x0400009b, 0x00000001, 0x00000001, 0x00000001,
19694         0x04000036, 0x00100032, 0x00000000, 0x00021046, 0x08000036, 0x001000c2, 0x00000000, 0x00004002,
19695         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8900002d, 0x800000c2, 0x00155543, 0x00100012,
19696         0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x060000a4, 0x0011e0f2, 0x00000000,
19697         0x00021546, 0x00100006, 0x00000000, 0x0100003e,
19698     };
19699     static const DWORD ps_code[] =
19700     {
19701 #if 0
19702         Texture2D<float> t;
19703 
19704         float main(float4 position : SV_Position) : SV_Target
19705         {
19706             return t[int2(position.x, position.y)];
19707         }
19708 #endif
19709         0x43425844, 0x0beace24, 0x5e10b05b, 0x742de364, 0xb2b65d2b, 0x00000001, 0x00000140, 0x00000003,
19710         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
19711         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
19712         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
19713         0x00000000, 0x00000e01, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000a4, 0x00000040,
19714         0x00000029, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000,
19715         0x00000001, 0x03000065, 0x00102012, 0x00000000, 0x02000068, 0x00000001, 0x0500001b, 0x00100032,
19716         0x00000000, 0x00101046, 0x00000000, 0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000,
19717         0x00000000, 0x00000000, 0x00000000, 0x0700002d, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
19718         0x00107e46, 0x00000000, 0x05000036, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e,
19719     };
19720     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
19721     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
19722     static const float tests[] = {0.00f, 0.25f, 0.75f, 1.00f};
19723 
19724     memset(&desc, 0, sizeof(desc));
19725     desc.rt_format = DXGI_FORMAT_R32_FLOAT;
19726     desc.no_root_signature = true;
19727     if (!init_test_context(&context, &desc))
19728         return;
19729     device = context.device;
19730     command_list = context.list;
19731     queue = context.queue;
19732 
19733     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
19734     descriptor_ranges[0].NumDescriptors = 1;
19735     descriptor_ranges[0].BaseShaderRegister = 0;
19736     descriptor_ranges[0].RegisterSpace = 0;
19737     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
19738     descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
19739     descriptor_ranges[1].NumDescriptors = 1;
19740     descriptor_ranges[1].BaseShaderRegister = 0;
19741     descriptor_ranges[1].RegisterSpace = 0;
19742     descriptor_ranges[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
19743     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
19744     root_parameters[0].DescriptorTable.NumDescriptorRanges = 2;
19745     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
19746     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
19747     root_signature_desc.NumParameters = 1;
19748     root_signature_desc.pParameters = root_parameters;
19749     root_signature_desc.NumStaticSamplers = 0;
19750     root_signature_desc.pStaticSamplers = NULL;
19751     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
19752     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
19753     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
19754 
19755     pipeline_state = create_compute_pipeline_state(device, context.root_signature,
19756             shader_bytecode(cs_code, sizeof(cs_code)));
19757     context.pipeline_state = create_pipeline_state(context.device,
19758             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
19759 
19760     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
19761 
19762     init_depth_stencil(&ds, device, context.render_target_desc.Width,
19763             context.render_target_desc.Height, 1, 1, DXGI_FORMAT_R32_TYPELESS,
19764             DXGI_FORMAT_D32_FLOAT, NULL);
19765     memset(&srv_desc, 0, sizeof(srv_desc));
19766     srv_desc.Format = DXGI_FORMAT_R32_FLOAT;
19767     srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
19768     srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
19769     srv_desc.Texture2D.MipLevels = 1;
19770     ID3D12Device_CreateShaderResourceView(device, ds.texture, &srv_desc,
19771             get_cpu_descriptor_handle(&context, heap, 0));
19772 
19773     texture = create_default_texture(device, 32, 32, DXGI_FORMAT_R16_UNORM,
19774             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
19775     ID3D12Device_CreateUnorderedAccessView(device, texture, NULL, NULL,
19776             get_cpu_descriptor_handle(&context, heap, 1));
19777 
19778     for (i = 0; i < ARRAY_SIZE(tests); ++i)
19779     {
19780         vkd3d_test_set_context("Test %u", i);
19781 
19782         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
19783                 D3D12_CLEAR_FLAG_DEPTH, tests[i], 0, 0, NULL);
19784         transition_sub_resource_state(command_list, ds.texture, 0,
19785                 D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
19786 
19787         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
19788         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
19789         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
19790         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
19791 
19792         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
19793 
19794         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
19795         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
19796         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
19797                 ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
19798         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
19799         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
19800 
19801         ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
19802         ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
19803         ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0,
19804                 ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
19805         ID3D12GraphicsCommandList_Dispatch(command_list, 32, 32, 1);
19806 
19807         transition_sub_resource_state(command_list, context.render_target, 0,
19808                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
19809         check_sub_resource_float(context.render_target, 0, queue, command_list, tests[i], 2);
19810 
19811         reset_command_list(command_list, context.allocator);
19812         transition_sub_resource_state(command_list, texture, 0,
19813                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
19814         check_sub_resource_uint16(texture, 0, queue, command_list, tests[i] * UINT16_MAX, 2);
19815 
19816         reset_command_list(command_list, context.allocator);
19817         transition_sub_resource_state(command_list, context.render_target, 0,
19818                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
19819         transition_sub_resource_state(command_list, texture, 0,
19820                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
19821         transition_sub_resource_state(command_list, ds.texture, 0,
19822                 D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE);
19823     }
19824     vkd3d_test_set_context(NULL);
19825 
19826     destroy_depth_stencil(&ds);
19827     ID3D12Resource_Release(texture);
19828     ID3D12DescriptorHeap_Release(heap);
19829     ID3D12PipelineState_Release(pipeline_state);
19830     destroy_test_context(&context);
19831 }
19832 
test_depth_read_only_view(void)19833 static void test_depth_read_only_view(void)
19834 {
19835     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
19836     ID3D12GraphicsCommandList *command_list;
19837     D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc;
19838     D3D12_CPU_DESCRIPTOR_HANDLE dsv_handle;
19839     struct depth_stencil_resource ds;
19840     struct test_context_desc desc;
19841     D3D12_CLEAR_VALUE clear_value;
19842     struct test_context context;
19843     ID3D12DescriptorHeap *heap;
19844     ID3D12CommandQueue *queue;
19845     ID3D12Device *device;
19846     HRESULT hr;
19847 
19848     static const DWORD ps_code[] =
19849     {
19850 #if 0
19851         float4 color;
19852 
19853         float4 main(float4 position : SV_POSITION) : SV_Target
19854         {
19855             return color;
19856         }
19857 #endif
19858         0x43425844, 0xd18ead43, 0x8b8264c1, 0x9c0a062d, 0xfc843226, 0x00000001, 0x000000e0, 0x00000003,
19859         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
19860         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49,
19861         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
19862         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000044, 0x00000050,
19863         0x00000011, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2,
19864         0x00000000, 0x06000036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e,
19865     };
19866     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
19867     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
19868     static const float green[] = {0.0f, 1.0f, 0.0f, 1.0f};
19869     static const float red[] = {1.0f, 0.0f, 0.0f, 1.0f};
19870 
19871     memset(&desc, 0, sizeof(desc));
19872     desc.no_root_signature = true;
19873     if (!init_test_context(&context, &desc))
19874         return;
19875     device = context.device;
19876     command_list = context.list;
19877     queue = context.queue;
19878 
19879     context.root_signature = create_32bit_constants_root_signature(device,
19880             0, 4, D3D12_SHADER_VISIBILITY_PIXEL);
19881 
19882     init_pipeline_state_desc(&pso_desc, context.root_signature,
19883             context.render_target_desc.Format, NULL, &ps, NULL);
19884     pso_desc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
19885     pso_desc.DepthStencilState.DepthEnable = true;
19886     pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
19887     pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_GREATER;
19888     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
19889             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
19890     ok(SUCCEEDED(hr), "Failed to create graphics pipeline state, hr %#x.\n", hr);
19891 
19892     heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1);
19893 
19894     clear_value.Format = DXGI_FORMAT_D32_FLOAT;
19895     clear_value.DepthStencil.Depth = 0.5f;
19896     clear_value.DepthStencil.Stencil = 0;
19897     init_depth_stencil(&ds, device, context.render_target_desc.Width,
19898             context.render_target_desc.Height, 1, 1, DXGI_FORMAT_R32_TYPELESS,
19899             DXGI_FORMAT_D32_FLOAT, &clear_value);
19900     memset(&dsv_desc, 0, sizeof(dsv_desc));
19901     dsv_desc.Format = DXGI_FORMAT_D32_FLOAT;
19902     dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
19903     dsv_desc.Flags = D3D12_DSV_FLAG_READ_ONLY_DEPTH;
19904     dsv_handle = get_cpu_descriptor_handle(&context, heap, 0);
19905     ID3D12Device_CreateDepthStencilView(device, ds.texture, &dsv_desc, dsv_handle);
19906 
19907     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
19908             D3D12_CLEAR_FLAG_DEPTH, 0.5f, 0, 0, NULL);
19909     transition_sub_resource_state(command_list, ds.texture, 0,
19910             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_DEPTH_READ);
19911 
19912     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
19913     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, &dsv_handle);
19914     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
19915 
19916     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
19917     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
19918     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
19919 
19920     context.viewport.MinDepth = 0.6f;
19921     context.viewport.MaxDepth = 0.6f;
19922     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
19923     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, green, 0);
19924     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
19925 
19926     context.viewport.MinDepth = 0.4f;
19927     context.viewport.MaxDepth = 0.4f;
19928     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
19929     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, red, 0);
19930     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
19931 
19932     transition_sub_resource_state(command_list, context.render_target, 0,
19933             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
19934     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
19935 
19936     reset_command_list(command_list, context.allocator);
19937     transition_sub_resource_state(command_list, ds.texture, 0,
19938             D3D12_RESOURCE_STATE_DEPTH_READ, D3D12_RESOURCE_STATE_COPY_SOURCE);
19939     check_sub_resource_float(ds.texture, 0, queue, command_list, 0.5f, 2);
19940 
19941     destroy_depth_stencil(&ds);
19942     ID3D12DescriptorHeap_Release(heap);
19943     destroy_test_context(&context);
19944 }
19945 
test_stencil_load(void)19946 static void test_stencil_load(void)
19947 {
19948     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
19949     D3D12_DESCRIPTOR_RANGE descriptor_ranges[2];
19950     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
19951     D3D12_ROOT_PARAMETER root_parameters[1];
19952     ID3D12GraphicsCommandList *command_list;
19953     ID3D12PipelineState *pipeline_state;
19954     struct depth_stencil_resource ds;
19955     struct test_context_desc desc;
19956     struct test_context context;
19957     ID3D12DescriptorHeap *heap;
19958     ID3D12CommandQueue *queue;
19959     struct uvec4 uvec4 = {0};
19960     ID3D12Resource *texture;
19961     ID3D12Device *device;
19962     unsigned int i;
19963     HRESULT hr;
19964 
19965     static const DWORD cs_code[] =
19966     {
19967 #if 0
19968         Texture2D<uint4> t;
19969         RWTexture2D<uint4> u;
19970 
19971         [numthreads(1, 1, 1)]
19972         void main(uint2 id : SV_GroupID)
19973         {
19974             u[id] = t[id];
19975         }
19976 #endif
19977         0x43425844, 0x0b41fa64, 0xd64df766, 0xc4c98283, 0xb810dc2b, 0x00000001, 0x00000110, 0x00000003,
19978         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
19979         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000bc, 0x00050050, 0x0000002f, 0x0100086a,
19980         0x04001858, 0x00107000, 0x00000000, 0x00004444, 0x0400189c, 0x0011e000, 0x00000000, 0x00004444,
19981         0x0200005f, 0x00021032, 0x02000068, 0x00000001, 0x0400009b, 0x00000001, 0x00000001, 0x00000001,
19982         0x04000036, 0x00100032, 0x00000000, 0x00021046, 0x08000036, 0x001000c2, 0x00000000, 0x00004002,
19983         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8900002d, 0x800000c2, 0x00111103, 0x001000f2,
19984         0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x060000a4, 0x0011e0f2, 0x00000000,
19985         0x00021546, 0x00100e46, 0x00000000, 0x0100003e,
19986     };
19987     static const DWORD ps_code[] =
19988     {
19989 #if 0
19990         Texture2D<uint4> t;
19991 
19992         uint4 main(float4 position : SV_Position) : SV_Target
19993         {
19994             return t[int2(position.x, position.y)];
19995         }
19996 #endif
19997         0x43425844, 0x9ad18dbc, 0x98de0e54, 0xe3c15d5b, 0xac8b580a, 0x00000001, 0x00000138, 0x00000003,
19998         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
19999         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
20000         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001,
20001         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000009c, 0x00000050,
20002         0x00000027, 0x0100086a, 0x04001858, 0x00107000, 0x00000000, 0x00004444, 0x04002064, 0x00101032,
20003         0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0500001b,
20004         0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x08000036, 0x001000c2, 0x00000000, 0x00004002,
20005         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8900002d, 0x800000c2, 0x00111103, 0x001020f2,
20006         0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0100003e,
20007     };
20008     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
20009     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
20010     static unsigned int tests[] = {0, 50, 75, 100, 150, 200, 255};
20011 
20012     memset(&desc, 0, sizeof(desc));
20013     desc.rt_format = DXGI_FORMAT_R32G32B32A32_UINT;
20014     desc.no_root_signature = true;
20015     if (!init_test_context(&context, &desc))
20016         return;
20017     device = context.device;
20018     command_list = context.list;
20019     queue = context.queue;
20020 
20021     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
20022     descriptor_ranges[0].NumDescriptors = 1;
20023     descriptor_ranges[0].BaseShaderRegister = 0;
20024     descriptor_ranges[0].RegisterSpace = 0;
20025     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
20026     descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
20027     descriptor_ranges[1].NumDescriptors = 1;
20028     descriptor_ranges[1].BaseShaderRegister = 0;
20029     descriptor_ranges[1].RegisterSpace = 0;
20030     descriptor_ranges[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
20031     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
20032     root_parameters[0].DescriptorTable.NumDescriptorRanges = 2;
20033     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
20034     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
20035     root_signature_desc.NumParameters = 1;
20036     root_signature_desc.pParameters = root_parameters;
20037     root_signature_desc.NumStaticSamplers = 0;
20038     root_signature_desc.pStaticSamplers = NULL;
20039     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
20040     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
20041     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
20042 
20043     pipeline_state = create_compute_pipeline_state(device, context.root_signature,
20044             shader_bytecode(cs_code, sizeof(cs_code)));
20045     context.pipeline_state = create_pipeline_state(context.device,
20046             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
20047 
20048     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
20049 
20050     init_depth_stencil(&ds, device, context.render_target_desc.Width,
20051             context.render_target_desc.Height, 1, 1, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, NULL);
20052     memset(&srv_desc, 0, sizeof(srv_desc));
20053     srv_desc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
20054     srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
20055     srv_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
20056             D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
20057             D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
20058             D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
20059             D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1);
20060     srv_desc.Texture2D.MipLevels = 1;
20061     srv_desc.Texture2D.PlaneSlice = 1;
20062     ID3D12Device_CreateShaderResourceView(device, ds.texture, &srv_desc,
20063             get_cpu_descriptor_handle(&context, heap, 0));
20064 
20065     texture = create_default_texture(device, 32, 32, DXGI_FORMAT_R32G32B32A32_UINT,
20066             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
20067     ID3D12Device_CreateUnorderedAccessView(device, texture, NULL, NULL,
20068             get_cpu_descriptor_handle(&context, heap, 1));
20069 
20070     for (i = 0; i < ARRAY_SIZE(tests); ++i)
20071     {
20072         vkd3d_test_set_context("Test %u", i);
20073 
20074         uvec4.x = uvec4.y = uvec4.z = uvec4.w = tests[i];
20075 
20076         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
20077                 D3D12_CLEAR_FLAG_STENCIL, 0.0f, tests[i], 0, NULL);
20078         transition_sub_resource_state(command_list, ds.texture, 0,
20079                 D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
20080 
20081         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
20082         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
20083         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
20084         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
20085 
20086         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
20087 
20088         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
20089         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
20090         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
20091                 ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
20092         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
20093         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
20094 
20095         ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
20096         ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
20097         ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0,
20098                 ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
20099         ID3D12GraphicsCommandList_Dispatch(command_list, 32, 32, 1);
20100 
20101         transition_sub_resource_state(command_list, context.render_target, 0,
20102                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
20103         check_sub_resource_uvec4(context.render_target, 0, queue, command_list, &uvec4);
20104 
20105         reset_command_list(command_list, context.allocator);
20106         transition_sub_resource_state(command_list, texture, 0,
20107                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
20108         check_sub_resource_uvec4(texture, 0, queue, command_list, &uvec4);
20109 
20110         reset_command_list(command_list, context.allocator);
20111         transition_sub_resource_state(command_list, context.render_target, 0,
20112                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
20113         transition_sub_resource_state(command_list, texture, 0,
20114                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
20115         transition_sub_resource_state(command_list, ds.texture, 0,
20116                 D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE);
20117     }
20118     vkd3d_test_set_context(NULL);
20119 
20120     destroy_depth_stencil(&ds);
20121     ID3D12Resource_Release(texture);
20122     ID3D12DescriptorHeap_Release(heap);
20123     ID3D12PipelineState_Release(pipeline_state);
20124     destroy_test_context(&context);
20125 }
20126 
test_typed_buffer_uav(void)20127 static void test_typed_buffer_uav(void)
20128 {
20129     D3D12_CPU_DESCRIPTOR_HANDLE cpu_descriptor_handle;
20130     D3D12_GPU_DESCRIPTOR_HANDLE gpu_descriptor_handle;
20131     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
20132     D3D12_DESCRIPTOR_RANGE descriptor_ranges[1];
20133     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
20134     ID3D12GraphicsCommandList *command_list;
20135     D3D12_ROOT_PARAMETER root_parameters[1];
20136     ID3D12DescriptorHeap *descriptor_heap;
20137     ID3D12RootSignature *root_signature;
20138     ID3D12PipelineState *pipeline_state;
20139     struct resource_readback rb;
20140     struct test_context context;
20141     ID3D12CommandQueue *queue;
20142     ID3D12Resource *resource;
20143     ID3D12Device *device;
20144     HRESULT hr;
20145 
20146     static const DWORD cs_code[] =
20147     {
20148 #if 0
20149         RWBuffer<float> buffer;
20150 
20151         [numthreads(32, 1, 1)]
20152         void main(uint3 group_id : SV_groupID, uint group_index : SV_GroupIndex)
20153         {
20154             uint global_index = 32 * group_id.x + group_index;
20155             buffer[global_index] = 0.5f;
20156         }
20157 #endif
20158         0x43425844, 0xcc416762, 0xde23c7b7, 0x4012ae1f, 0xaed30ba4, 0x00000001, 0x000000e0, 0x00000003,
20159         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
20160         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x0000008c, 0x00050050, 0x00000023, 0x0100086a,
20161         0x0400089c, 0x0011e000, 0x00000000, 0x00005555, 0x0200005f, 0x00024000, 0x0200005f, 0x00021012,
20162         0x02000068, 0x00000001, 0x0400009b, 0x00000020, 0x00000001, 0x00000001, 0x07000023, 0x00100012,
20163         0x00000000, 0x0002100a, 0x00004001, 0x00000020, 0x0002400a, 0x0a0000a4, 0x0011e0f2, 0x00000000,
20164         0x00100006, 0x00000000, 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x0100003e,
20165     };
20166 
20167     if (!init_compute_test_context(&context))
20168         return;
20169     device = context.device;
20170     command_list = context.list;
20171     queue = context.queue;
20172 
20173     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
20174     descriptor_ranges[0].NumDescriptors = 1;
20175     descriptor_ranges[0].BaseShaderRegister = 0;
20176     descriptor_ranges[0].RegisterSpace = 0;
20177     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
20178     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
20179     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
20180     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
20181     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
20182     root_signature_desc.NumParameters = 1;
20183     root_signature_desc.pParameters = root_parameters;
20184     root_signature_desc.NumStaticSamplers = 0;
20185     root_signature_desc.pStaticSamplers = NULL;
20186     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
20187     hr = create_root_signature(device, &root_signature_desc, &root_signature);
20188     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
20189 
20190     pipeline_state = create_compute_pipeline_state(device, root_signature,
20191             shader_bytecode(cs_code, sizeof(cs_code)));
20192 
20193     descriptor_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
20194 
20195     cpu_descriptor_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(descriptor_heap);
20196     gpu_descriptor_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap);
20197 
20198     resource = create_default_buffer(device, 64 * sizeof(float),
20199             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
20200 
20201     uav_desc.Format = DXGI_FORMAT_R32_FLOAT;
20202     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
20203     uav_desc.Buffer.FirstElement = 0;
20204     uav_desc.Buffer.NumElements = 64;
20205     uav_desc.Buffer.StructureByteStride = 0;
20206     uav_desc.Buffer.CounterOffsetInBytes = 0;
20207     uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
20208     ID3D12Device_CreateUnorderedAccessView(device, resource, NULL, &uav_desc, cpu_descriptor_handle);
20209 
20210     ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
20211     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, root_signature);
20212     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
20213     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_descriptor_handle);
20214     ID3D12GraphicsCommandList_Dispatch(command_list, 2, 1, 1);
20215 
20216     transition_sub_resource_state(command_list, resource, 0,
20217             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
20218 
20219     get_buffer_readback_with_command_list(resource, uav_desc.Format, &rb, queue, command_list);
20220     check_readback_data_float(&rb, NULL, 0.5f, 0);
20221     release_resource_readback(&rb);
20222 
20223     ID3D12Resource_Release(resource);
20224     ID3D12RootSignature_Release(root_signature);
20225     ID3D12PipelineState_Release(pipeline_state);
20226     ID3D12DescriptorHeap_Release(descriptor_heap);
20227     destroy_test_context(&context);
20228 }
20229 
test_typed_uav_store(void)20230 static void test_typed_uav_store(void)
20231 {
20232     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
20233     D3D12_DESCRIPTOR_RANGE descriptor_ranges[1];
20234     ID3D12GraphicsCommandList *command_list;
20235     D3D12_ROOT_PARAMETER root_parameters[2];
20236     ID3D12DescriptorHeap *descriptor_heap;
20237     struct test_context context;
20238     ID3D12CommandQueue *queue;
20239     ID3D12Resource *resource;
20240     ID3D12Device *device;
20241     unsigned int i;
20242     HRESULT hr;
20243 
20244     static const DWORD cs_float_code[] =
20245     {
20246 #if 0
20247         RWTexture2D<float> u;
20248 
20249         float f;
20250 
20251         [numthreads(1, 1, 1)]
20252         void main(uint2 id : SV_GroupID)
20253         {
20254             u[id] = f;
20255         }
20256 #endif
20257         0x43425844, 0xc3add41b, 0x67df51b1, 0x2b887930, 0xcb1ee991, 0x00000001, 0x000000b8, 0x00000003,
20258         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
20259         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000064, 0x00050050, 0x00000019, 0x0100086a,
20260         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0400189c, 0x0011e000, 0x00000000, 0x00005555,
20261         0x0200005f, 0x00021032, 0x0400009b, 0x00000001, 0x00000001, 0x00000001, 0x070000a4, 0x0011e0f2,
20262         0x00000000, 0x00021546, 0x00208006, 0x00000000, 0x00000000, 0x0100003e,
20263     };
20264     static const struct
20265     {
20266         DXGI_FORMAT format;
20267         float constant;
20268         union
20269         {
20270             float f;
20271             uint16_t u16;
20272         } result;
20273     }
20274     tests[] =
20275     {
20276         {DXGI_FORMAT_R16_FLOAT, 1.0f, {.u16 = 0x3c00}},
20277         {DXGI_FORMAT_R16_FLOAT, 0.5f, {.u16 = 0x3800}},
20278 
20279         {DXGI_FORMAT_R16_UNORM, 0.5f, {.u16 = 32768}},
20280 
20281         {DXGI_FORMAT_R32_FLOAT, 0.0f, {.f = 0.0f}},
20282         {DXGI_FORMAT_R32_FLOAT, 0.5f, {.f = 0.5f}},
20283         {DXGI_FORMAT_R32_FLOAT, 1.0f, {.f = 1.0f}},
20284     };
20285 
20286     if (!init_compute_test_context(&context))
20287         return;
20288     device = context.device;
20289     command_list = context.list;
20290     queue = context.queue;
20291 
20292     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
20293     descriptor_ranges[0].NumDescriptors = 1;
20294     descriptor_ranges[0].BaseShaderRegister = 0;
20295     descriptor_ranges[0].RegisterSpace = 0;
20296     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
20297     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
20298     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
20299     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
20300     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
20301     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
20302     root_parameters[1].Constants.ShaderRegister = 0;
20303     root_parameters[1].Constants.RegisterSpace = 0;
20304     root_parameters[1].Constants.Num32BitValues = 1;
20305     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
20306     root_signature_desc.NumParameters = 2;
20307     root_signature_desc.pParameters = root_parameters;
20308     root_signature_desc.NumStaticSamplers = 0;
20309     root_signature_desc.pStaticSamplers = NULL;
20310     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
20311     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
20312     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
20313 
20314     context.pipeline_state = create_compute_pipeline_state(device, context.root_signature,
20315             shader_bytecode(cs_float_code, sizeof(cs_float_code)));
20316 
20317     descriptor_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
20318 
20319     for (i = 0; i < ARRAY_SIZE(tests); ++i)
20320     {
20321         vkd3d_test_set_context("Test %u", i);
20322 
20323         resource = create_default_texture(device, 32, 32, tests[i].format,
20324                 D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
20325         ID3D12Device_CreateUnorderedAccessView(device, resource, NULL, NULL,
20326                 ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(descriptor_heap));
20327 
20328         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
20329         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
20330         ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
20331         ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0,
20332                 ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap));
20333         ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(command_list, 1,
20334                 1, &tests[i].constant, 0);
20335         ID3D12GraphicsCommandList_Dispatch(command_list, 32, 32, 1);
20336 
20337         transition_sub_resource_state(command_list, resource, 0,
20338                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
20339         switch (tests[i].format)
20340         {
20341             default:
20342                 trace("Unhandled format %#x.\n", tests[i].format);
20343                 /* fall-through */
20344             case DXGI_FORMAT_R32_FLOAT:
20345                 check_sub_resource_float(resource, 0, queue, command_list, tests[i].result.f, 2);
20346                 break;
20347             case DXGI_FORMAT_R16_FLOAT:
20348             case DXGI_FORMAT_R16_UNORM:
20349                 check_sub_resource_uint16(resource, 0, queue, command_list, tests[i].result.u16, 2);
20350                 break;
20351         }
20352 
20353         ID3D12Resource_Release(resource);
20354 
20355         reset_command_list(command_list, context.allocator);
20356     }
20357     vkd3d_test_set_context(NULL);
20358 
20359     ID3D12DescriptorHeap_Release(descriptor_heap);
20360     destroy_test_context(&context);
20361 }
20362 
test_compute_shader_registers(void)20363 static void test_compute_shader_registers(void)
20364 {
20365     struct data
20366     {
20367         unsigned int group_id[3];
20368         unsigned int group_index;
20369         unsigned int dispatch_id[3];
20370         unsigned int thread_id[3];
20371     };
20372 
20373     D3D12_CPU_DESCRIPTOR_HANDLE cpu_descriptor_handle;
20374     D3D12_GPU_DESCRIPTOR_HANDLE gpu_descriptor_handle;
20375     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
20376     D3D12_DESCRIPTOR_RANGE descriptor_ranges[1];
20377     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
20378     ID3D12GraphicsCommandList *command_list;
20379     D3D12_ROOT_PARAMETER root_parameters[2];
20380     unsigned int i, x, y, group_x, group_y;
20381     ID3D12DescriptorHeap *descriptor_heap;
20382     struct resource_readback rb;
20383     struct test_context context;
20384     ID3D12CommandQueue *queue;
20385     ID3D12Resource *resource;
20386     const struct data *data;
20387     struct uvec4 dimensions;
20388     ID3D12Device *device;
20389     HRESULT hr;
20390 
20391     static const DWORD cs_code[] =
20392     {
20393 #if 0
20394         struct data
20395         {
20396             uint3 group_id;
20397             uint group_index;
20398             uint3 dispatch_id;
20399             uint3 group_thread_id;
20400         };
20401 
20402         RWStructuredBuffer<data> u;
20403 
20404         uint2 dim;
20405 
20406         [numthreads(3, 2, 1)]
20407         void main(uint3 group_id : SV_GroupID,
20408                 uint group_index : SV_GroupIndex,
20409                 uint3 dispatch_id : SV_DispatchThreadID,
20410                 uint3 group_thread_id : SV_GroupThreadID)
20411         {
20412             uint i = dispatch_id.x + dispatch_id.y * 3 * dim.x;
20413             u[i].group_id = group_id;
20414             u[i].group_index = group_index;
20415             u[i].dispatch_id = dispatch_id;
20416             u[i].group_thread_id = group_thread_id;
20417         }
20418 #endif
20419         0x43425844, 0xf0bce218, 0xfc1e8267, 0xe6d57544, 0x342df592, 0x00000001, 0x000001a4, 0x00000003,
20420         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
20421         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000150, 0x00050050, 0x00000054, 0x0100086a,
20422         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0400009e, 0x0011e000, 0x00000000, 0x00000028,
20423         0x0200005f, 0x00024000, 0x0200005f, 0x00021072, 0x0200005f, 0x00022072, 0x0200005f, 0x00020072,
20424         0x02000068, 0x00000002, 0x0400009b, 0x00000003, 0x00000002, 0x00000001, 0x04000036, 0x00100072,
20425         0x00000000, 0x00021246, 0x04000036, 0x00100082, 0x00000000, 0x0002400a, 0x08000026, 0x0000d000,
20426         0x00100012, 0x00000001, 0x0002001a, 0x0020800a, 0x00000000, 0x00000000, 0x08000023, 0x00100012,
20427         0x00000001, 0x0010000a, 0x00000001, 0x00004001, 0x00000003, 0x0002000a, 0x090000a8, 0x0011e0f2,
20428         0x00000000, 0x0010000a, 0x00000001, 0x00004001, 0x00000000, 0x00100e46, 0x00000000, 0x04000036,
20429         0x00100072, 0x00000000, 0x00020246, 0x04000036, 0x00100082, 0x00000000, 0x0002200a, 0x090000a8,
20430         0x0011e0f2, 0x00000000, 0x0010000a, 0x00000001, 0x00004001, 0x00000010, 0x00100e46, 0x00000000,
20431         0x080000a8, 0x0011e032, 0x00000000, 0x0010000a, 0x00000001, 0x00004001, 0x00000020, 0x00022596,
20432         0x0100003e,
20433     };
20434 
20435     if (!init_compute_test_context(&context))
20436         return;
20437     device = context.device;
20438     command_list = context.list;
20439     queue = context.queue;
20440 
20441     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
20442     descriptor_ranges[0].NumDescriptors = 1;
20443     descriptor_ranges[0].BaseShaderRegister = 0;
20444     descriptor_ranges[0].RegisterSpace = 0;
20445     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
20446     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
20447     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
20448     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
20449     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
20450     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
20451     root_parameters[1].Constants.ShaderRegister = 0;
20452     root_parameters[1].Constants.RegisterSpace = 0;
20453     root_parameters[1].Constants.Num32BitValues = 4;
20454     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
20455     root_signature_desc.NumParameters = 2;
20456     root_signature_desc.pParameters = root_parameters;
20457     root_signature_desc.NumStaticSamplers = 0;
20458     root_signature_desc.pStaticSamplers = NULL;
20459     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
20460     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
20461     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
20462 
20463     context.pipeline_state = create_compute_pipeline_state(device, context.root_signature,
20464             shader_bytecode(cs_code, sizeof(cs_code)));
20465 
20466     resource = create_default_buffer(device, 10240,
20467             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
20468 
20469     descriptor_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
20470     cpu_descriptor_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(descriptor_heap);
20471     gpu_descriptor_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap);
20472 
20473     memset(&uav_desc, 0, sizeof(uav_desc));
20474     uav_desc.Format = DXGI_FORMAT_UNKNOWN;
20475     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
20476     uav_desc.Buffer.FirstElement = 0;
20477     uav_desc.Buffer.NumElements = 256;
20478     uav_desc.Buffer.StructureByteStride = 40;
20479     ID3D12Device_CreateUnorderedAccessView(device, resource, NULL, &uav_desc, cpu_descriptor_handle);
20480 
20481     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
20482     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
20483     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
20484     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_descriptor_handle);
20485     dimensions.x = 2;
20486     dimensions.y = 3;
20487     dimensions.z = 1;
20488     dimensions.w = 0;
20489     ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(command_list, 1, 4, &dimensions, 0);
20490     ID3D12GraphicsCommandList_Dispatch(command_list, dimensions.x, dimensions.y, dimensions.z);
20491 
20492     transition_resource_state(command_list, resource,
20493             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
20494 
20495     get_buffer_readback_with_command_list(resource, uav_desc.Format, &rb, queue, command_list);
20496     i = 0;
20497     data = rb.data;
20498     for (y = 0; y < dimensions.y; ++y)
20499     {
20500         for (group_y = 0; group_y < 2; ++group_y)
20501         {
20502             for (x = 0; x < dimensions.x; ++x)
20503             {
20504                 for (group_x = 0; group_x < 3; ++group_x)
20505                 {
20506                     const unsigned int dispatch_id[2] = {x * 3 + group_x, y * 2 + group_y};
20507                     const unsigned int group_index = group_y * 3 + group_x;
20508                     const struct data *d = &data[i];
20509 
20510                     ok(d->group_id[0] == x && d->group_id[1] == y && !d->group_id[2],
20511                             "Got group id (%u, %u, %u), expected (%u, %u, %u) at %u (%u, %u, %u, %u).\n",
20512                             d->group_id[0], d->group_id[1], d->group_id[2], x, y, 0,
20513                             i, x, y, group_x, group_y);
20514                     ok(d->group_index == group_index,
20515                             "Got group index %u, expected %u at %u (%u, %u, %u, %u).\n",
20516                             d->group_index, group_index, i, x, y, group_x, group_y);
20517                     ok(d->dispatch_id[0] == dispatch_id[0] && d->dispatch_id[1] == dispatch_id[1]
20518                             && !d->dispatch_id[2],
20519                             "Got dispatch id (%u, %u, %u), expected (%u, %u, %u) "
20520                             "at %u (%u, %u, %u, %u).\n",
20521                             d->dispatch_id[0], d->dispatch_id[1], d->dispatch_id[2],
20522                             dispatch_id[0], dispatch_id[1], 0,
20523                             i, x, y, group_x, group_y);
20524                     ok(d->thread_id[0] == group_x && d->thread_id[1] == group_y && !d->thread_id[2],
20525                             "Got group thread id (%u, %u, %u), expected (%u, %u, %u) "
20526                             "at %u (%u, %u, %u, %u).\n",
20527                             d->thread_id[0], d->thread_id[1], d->thread_id[2], group_x, group_y, 0,
20528                             i, x, y, group_x, group_y);
20529                     ++i;
20530                 }
20531             }
20532         }
20533     }
20534     release_resource_readback(&rb);
20535 
20536     ID3D12DescriptorHeap_Release(descriptor_heap);
20537     ID3D12Resource_Release(resource);
20538     destroy_test_context(&context);
20539 }
20540 
test_tgsm(void)20541 static void test_tgsm(void)
20542 {
20543     D3D12_GPU_DESCRIPTOR_HANDLE gpu_descriptor_handle;
20544     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
20545     D3D12_DESCRIPTOR_RANGE descriptor_ranges[1];
20546     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
20547     ID3D12DescriptorHeap *cpu_descriptor_heap;
20548     ID3D12GraphicsCommandList *command_list;
20549     D3D12_ROOT_PARAMETER root_parameters[1];
20550     ID3D12DescriptorHeap *descriptor_heap;
20551     ID3D12Resource *buffer, *buffer2;
20552     unsigned int data, expected;
20553     struct resource_readback rb;
20554     struct test_context context;
20555     ID3D12CommandQueue *queue;
20556     ID3D12Device *device;
20557     float float_data;
20558     unsigned int i;
20559     HRESULT hr;
20560 
20561     static const DWORD raw_tgsm_code[] =
20562     {
20563 #if 0
20564         RWByteAddressBuffer u;
20565         groupshared uint m;
20566 
20567         [numthreads(32, 1, 1)]
20568         void main(uint local_idx : SV_GroupIndex, uint group_id : SV_GroupID)
20569         {
20570             if (!local_idx)
20571                 m = group_id.x;
20572             GroupMemoryBarrierWithGroupSync();
20573             InterlockedAdd(m, group_id.x);
20574             GroupMemoryBarrierWithGroupSync();
20575             if (!local_idx)
20576                 u.Store(4 * group_id.x, m);
20577         }
20578 #endif
20579         0x43425844, 0x467df6d9, 0x5f56edda, 0x5c96b787, 0x60c91fb8, 0x00000001, 0x00000148, 0x00000003,
20580         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
20581         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000f4, 0x00050050, 0x0000003d, 0x0100086a,
20582         0x0300009d, 0x0011e000, 0x00000000, 0x0200005f, 0x00024000, 0x0200005f, 0x00021012, 0x02000068,
20583         0x00000001, 0x0400009f, 0x0011f000, 0x00000000, 0x00000004, 0x0400009b, 0x00000020, 0x00000001,
20584         0x00000001, 0x0200001f, 0x0002400a, 0x060000a6, 0x0011f012, 0x00000000, 0x00004001, 0x00000000,
20585         0x0002100a, 0x01000015, 0x010018be, 0x060000ad, 0x0011f000, 0x00000000, 0x00004001, 0x00000000,
20586         0x0002100a, 0x010018be, 0x0200001f, 0x0002400a, 0x06000029, 0x00100012, 0x00000000, 0x0002100a,
20587         0x00004001, 0x00000002, 0x070000a5, 0x00100022, 0x00000000, 0x00004001, 0x00000000, 0x0011f006,
20588         0x00000000, 0x070000a6, 0x0011e012, 0x00000000, 0x0010000a, 0x00000000, 0x0010001a, 0x00000000,
20589         0x01000015, 0x0100003e,
20590     };
20591     static const D3D12_SHADER_BYTECODE cs_raw_tgsm = {raw_tgsm_code, sizeof(raw_tgsm_code)};
20592     static const DWORD structured_tgsm_code[] =
20593     {
20594 #if 0
20595         #define GROUP_SIZE 32
20596 
20597         RWByteAddressBuffer u;
20598         RWByteAddressBuffer u2;
20599         groupshared uint m[GROUP_SIZE];
20600 
20601         [numthreads(GROUP_SIZE, 1, 1)]
20602         void main(uint local_idx : SV_GroupIndex, uint group_id : SV_GroupID)
20603         {
20604             uint sum, original, i;
20605 
20606             if (!local_idx)
20607             {
20608                 for (i = 0; i < GROUP_SIZE; ++i)
20609                     m[i] = 2 * group_id.x;
20610             }
20611             GroupMemoryBarrierWithGroupSync();
20612             InterlockedAdd(m[local_idx], 1);
20613             GroupMemoryBarrierWithGroupSync();
20614             for (i = 0, sum = 0; i < GROUP_SIZE; sum += m[i++]);
20615             u.InterlockedExchange(4 * group_id.x, sum, original);
20616             u2.Store(4 * group_id.x, original);
20617         }
20618 #endif
20619         0x43425844, 0x9d906c94, 0x81f5ad92, 0x11e860b2, 0x3623c824, 0x00000001, 0x000002c0, 0x00000003,
20620         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
20621         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x0000026c, 0x00050050, 0x0000009b, 0x0100086a,
20622         0x0300009d, 0x0011e000, 0x00000000, 0x0300009d, 0x0011e000, 0x00000001, 0x0200005f, 0x00024000,
20623         0x0200005f, 0x00021012, 0x02000068, 0x00000002, 0x050000a0, 0x0011f000, 0x00000000, 0x00000004,
20624         0x00000020, 0x0400009b, 0x00000020, 0x00000001, 0x00000001, 0x0200001f, 0x0002400a, 0x06000029,
20625         0x00100012, 0x00000000, 0x0002100a, 0x00004001, 0x00000001, 0x05000036, 0x00100022, 0x00000000,
20626         0x00004001, 0x00000000, 0x01000030, 0x07000050, 0x00100042, 0x00000000, 0x0010001a, 0x00000000,
20627         0x00004001, 0x00000020, 0x03040003, 0x0010002a, 0x00000000, 0x090000a8, 0x0011f012, 0x00000000,
20628         0x0010001a, 0x00000000, 0x00004001, 0x00000000, 0x0010000a, 0x00000000, 0x0700001e, 0x00100022,
20629         0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x00000001, 0x01000016, 0x01000015, 0x010018be,
20630         0x04000036, 0x00100012, 0x00000000, 0x0002400a, 0x05000036, 0x00100022, 0x00000000, 0x00004001,
20631         0x00000000, 0x070000ad, 0x0011f000, 0x00000000, 0x00100046, 0x00000000, 0x00004001, 0x00000001,
20632         0x010018be, 0x08000036, 0x00100032, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
20633         0x00000000, 0x01000030, 0x07000050, 0x00100042, 0x00000000, 0x0010001a, 0x00000000, 0x00004001,
20634         0x00000020, 0x03040003, 0x0010002a, 0x00000000, 0x0700001e, 0x00100022, 0x00000001, 0x0010001a,
20635         0x00000000, 0x00004001, 0x00000001, 0x090000a7, 0x00100042, 0x00000000, 0x0010001a, 0x00000000,
20636         0x00004001, 0x00000000, 0x0011f006, 0x00000000, 0x0700001e, 0x00100012, 0x00000001, 0x0010000a,
20637         0x00000000, 0x0010002a, 0x00000000, 0x05000036, 0x00100032, 0x00000000, 0x00100046, 0x00000001,
20638         0x01000016, 0x06000029, 0x00100022, 0x00000000, 0x0002100a, 0x00004001, 0x00000002, 0x090000b8,
20639         0x00100012, 0x00000001, 0x0011e000, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000,
20640         0x070000a6, 0x0011e012, 0x00000001, 0x0010001a, 0x00000000, 0x0010000a, 0x00000001, 0x0100003e,
20641     };
20642     static const D3D12_SHADER_BYTECODE cs_structured_tgsm = {structured_tgsm_code, sizeof(structured_tgsm_code)};
20643     static const DWORD structured_tgsm_float_code[] =
20644     {
20645 #if 0
20646         #define GROUP_SIZE 32
20647 
20648         struct data
20649         {
20650             float f;
20651             uint u;
20652         };
20653 
20654         RWBuffer<float> u;
20655         RWBuffer<uint> u2;
20656         groupshared data m[GROUP_SIZE];
20657 
20658         [numthreads(GROUP_SIZE, 1, 1)]
20659         void main(uint local_idx : SV_GroupIndex, uint group_id : SV_GroupID,
20660                 uint thread_id : SV_DispatchThreadID)
20661         {
20662             uint i;
20663             if (!local_idx)
20664             {
20665                 for (i = 0; i < GROUP_SIZE; ++i)
20666                 {
20667                     m[i].f = group_id.x;
20668                     m[i].u = group_id.x;
20669                 }
20670             }
20671             GroupMemoryBarrierWithGroupSync();
20672             for (i = 0; i < local_idx; ++i)
20673             {
20674                 m[local_idx].f += group_id.x;
20675                 m[local_idx].u += group_id.x;
20676             }
20677             u[thread_id.x] = m[local_idx].f;
20678             u2[thread_id.x] = m[local_idx].u;
20679         }
20680 #endif
20681         0x43425844, 0xaadf1a71, 0x16f60224, 0x89b6ce76, 0xb66fb96f, 0x00000001, 0x000002ac, 0x00000003,
20682         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
20683         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000258, 0x00050050, 0x00000096, 0x0100086a,
20684         0x0400089c, 0x0011e000, 0x00000000, 0x00005555, 0x0400089c, 0x0011e000, 0x00000001, 0x00004444,
20685         0x0200005f, 0x00024000, 0x0200005f, 0x00021012, 0x0200005f, 0x00020012, 0x02000068, 0x00000002,
20686         0x050000a0, 0x0011f000, 0x00000000, 0x00000008, 0x00000020, 0x0400009b, 0x00000020, 0x00000001,
20687         0x00000001, 0x0200001f, 0x0002400a, 0x04000056, 0x00100012, 0x00000000, 0x0002100a, 0x04000036,
20688         0x00100022, 0x00000000, 0x0002100a, 0x05000036, 0x00100042, 0x00000000, 0x00004001, 0x00000000,
20689         0x01000030, 0x07000050, 0x00100082, 0x00000000, 0x0010002a, 0x00000000, 0x00004001, 0x00000020,
20690         0x03040003, 0x0010003a, 0x00000000, 0x090000a8, 0x0011f032, 0x00000000, 0x0010002a, 0x00000000,
20691         0x00004001, 0x00000000, 0x00100046, 0x00000000, 0x0700001e, 0x00100042, 0x00000000, 0x0010002a,
20692         0x00000000, 0x00004001, 0x00000001, 0x01000016, 0x01000015, 0x010018be, 0x04000056, 0x00100012,
20693         0x00000000, 0x0002100a, 0x05000036, 0x00100022, 0x00000000, 0x00004001, 0x00000000, 0x01000030,
20694         0x06000050, 0x00100042, 0x00000000, 0x0010001a, 0x00000000, 0x0002400a, 0x03040003, 0x0010002a,
20695         0x00000000, 0x080000a7, 0x001000c2, 0x00000000, 0x0002400a, 0x00004001, 0x00000000, 0x0011f406,
20696         0x00000000, 0x07000000, 0x00100012, 0x00000001, 0x0010000a, 0x00000000, 0x0010002a, 0x00000000,
20697         0x0600001e, 0x00100022, 0x00000001, 0x0010003a, 0x00000000, 0x0002100a, 0x080000a8, 0x0011f032,
20698         0x00000000, 0x0002400a, 0x00004001, 0x00000000, 0x00100046, 0x00000001, 0x0700001e, 0x00100022,
20699         0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x00000001, 0x01000016, 0x080000a7, 0x00100032,
20700         0x00000000, 0x0002400a, 0x00004001, 0x00000000, 0x0011f046, 0x00000000, 0x060000a4, 0x0011e0f2,
20701         0x00000000, 0x00020006, 0x00100006, 0x00000000, 0x060000a4, 0x0011e0f2, 0x00000001, 0x00020006,
20702         0x00100556, 0x00000000, 0x0100003e,
20703     };
20704     static const D3D12_SHADER_BYTECODE cs_structured_tgsm_float
20705             = {structured_tgsm_float_code, sizeof(structured_tgsm_float_code)};
20706     static const unsigned int zero[4] = {0};
20707 
20708     if (!init_compute_test_context(&context))
20709         return;
20710     device = context.device;
20711     command_list = context.list;
20712     queue = context.queue;
20713 
20714     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
20715     descriptor_ranges[0].NumDescriptors = 2;
20716     descriptor_ranges[0].BaseShaderRegister = 0;
20717     descriptor_ranges[0].RegisterSpace = 0;
20718     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
20719     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
20720     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
20721     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
20722     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
20723     root_signature_desc.NumParameters = 1;
20724     root_signature_desc.pParameters = root_parameters;
20725     root_signature_desc.NumStaticSamplers = 0;
20726     root_signature_desc.pStaticSamplers = NULL;
20727     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
20728     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
20729     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
20730 
20731     buffer = create_default_buffer(device, 1024,
20732             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
20733 
20734     descriptor_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
20735     cpu_descriptor_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 2);
20736 
20737     gpu_descriptor_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap);
20738 
20739     memset(&uav_desc, 0, sizeof(uav_desc));
20740     uav_desc.Format = DXGI_FORMAT_R32_TYPELESS;
20741     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
20742     uav_desc.Buffer.FirstElement = 0;
20743     uav_desc.Buffer.NumElements = 256;
20744     uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
20745     ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc,
20746             get_cpu_descriptor_handle(&context, descriptor_heap, 0));
20747     ID3D12Device_CreateUnorderedAccessView(device, NULL, NULL, &uav_desc,
20748             get_cpu_descriptor_handle(&context, descriptor_heap, 1));
20749 
20750     /* cs_raw_tgsm */
20751     context.pipeline_state = create_compute_pipeline_state(device, context.root_signature, cs_raw_tgsm);
20752 
20753     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
20754     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
20755     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
20756     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_descriptor_handle);
20757     ID3D12GraphicsCommandList_Dispatch(command_list, 64, 1, 1);
20758 
20759     transition_resource_state(command_list, buffer,
20760             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
20761 
20762     get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
20763     for (i = 0; i < 64; ++i)
20764     {
20765         data = get_readback_uint(&rb, i, 0, 0);
20766         expected = 33 * i;
20767         ok(data == expected, "Got %u, expected %u (index %u).\n", data, expected, i);
20768     }
20769     release_resource_readback(&rb);
20770 
20771     ID3D12PipelineState_Release(context.pipeline_state);
20772 
20773     /* cs_structured_tgsm */
20774     reset_command_list(command_list, context.allocator);
20775 
20776     context.pipeline_state = create_compute_pipeline_state(device, context.root_signature, cs_structured_tgsm);
20777 
20778     buffer2 = create_default_buffer(device, 1024,
20779             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
20780 
20781     ID3D12Device_CreateUnorderedAccessView(device, buffer2, NULL, &uav_desc,
20782             get_cpu_descriptor_handle(&context, descriptor_heap, 1));
20783 
20784     ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc,
20785             get_cpu_descriptor_handle(&context, cpu_descriptor_heap, 0));
20786     ID3D12Device_CreateUnorderedAccessView(device, buffer2, NULL, &uav_desc,
20787             get_cpu_descriptor_handle(&context, cpu_descriptor_heap, 1));
20788 
20789     ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(command_list,
20790             get_gpu_descriptor_handle(&context, descriptor_heap, 0),
20791             get_cpu_descriptor_handle(&context, cpu_descriptor_heap, 0),
20792             buffer, zero, 0, NULL);
20793     ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(command_list,
20794             get_gpu_descriptor_handle(&context, descriptor_heap, 1),
20795             get_cpu_descriptor_handle(&context, cpu_descriptor_heap, 1),
20796             buffer2, zero, 0, NULL);
20797 
20798     gpu_descriptor_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap);
20799     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
20800     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
20801     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
20802     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_descriptor_handle);
20803     ID3D12GraphicsCommandList_Dispatch(command_list, 32, 1, 1);
20804 
20805     transition_resource_state(command_list, buffer,
20806             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
20807     transition_resource_state(command_list, buffer2,
20808             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
20809 
20810     get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
20811     for (i = 0; i < 32; ++i)
20812     {
20813         expected = 64 * i + 32;
20814         data = get_readback_uint(&rb, i, 0, 0);
20815         ok(data == expected, "Got %u, expected %u (index %u).\n", data, expected, i);
20816     }
20817     release_resource_readback(&rb);
20818     reset_command_list(command_list, context.allocator);
20819     get_buffer_readback_with_command_list(buffer2, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
20820     for (i = 0; i < 32; ++i)
20821     {
20822         expected = 64 * i + 32;
20823         data = get_readback_uint(&rb, i, 0, 0);
20824         ok(data == expected || !data, "Got %u, expected %u (index %u).\n", data, expected, i);
20825     }
20826     release_resource_readback(&rb);
20827 
20828     ID3D12PipelineState_Release(context.pipeline_state);
20829 
20830     /* cs_structured_tgsm_float */
20831     reset_command_list(command_list, context.allocator);
20832     transition_resource_state(command_list, buffer,
20833             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
20834     transition_resource_state(command_list, buffer2,
20835             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
20836 
20837     context.pipeline_state = create_compute_pipeline_state(device,
20838             context.root_signature, cs_structured_tgsm_float);
20839 
20840     uav_desc.Format = DXGI_FORMAT_R32_FLOAT;
20841     uav_desc.Buffer.Flags = 0;
20842     ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc,
20843             get_cpu_descriptor_handle(&context, descriptor_heap, 0));
20844     uav_desc.Format = DXGI_FORMAT_R32_UINT;
20845     ID3D12Device_CreateUnorderedAccessView(device, buffer2, NULL, &uav_desc,
20846             get_cpu_descriptor_handle(&context, descriptor_heap, 1));
20847 
20848     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
20849     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
20850     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
20851     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_descriptor_handle);
20852     ID3D12GraphicsCommandList_Dispatch(command_list, 3, 1, 1);
20853 
20854     transition_resource_state(command_list, buffer,
20855             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
20856     transition_resource_state(command_list, buffer2,
20857             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
20858 
20859     get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
20860     for (i = 0; i < 96; ++i)
20861     {
20862         expected = (i % 32 + 1) * (i / 32);
20863         float_data = get_readback_float(&rb, i, 0);
20864         ok(float_data == expected, "Got %.8e, expected %u (index %u).\n", float_data, expected, i);
20865     }
20866     release_resource_readback(&rb);
20867     reset_command_list(command_list, context.allocator);
20868     get_buffer_readback_with_command_list(buffer2, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
20869     for (i = 0; i < 96; ++i)
20870     {
20871         expected = (i % 32 + 1) * (i / 32);
20872         data = get_readback_uint(&rb, i, 0, 0);
20873         ok(data == expected, "Got %u, expected %u (index %u).\n", data, expected, i);
20874     }
20875     release_resource_readback(&rb);
20876 
20877     ID3D12Resource_Release(buffer);
20878     ID3D12Resource_Release(buffer2);
20879     ID3D12DescriptorHeap_Release(cpu_descriptor_heap);
20880     ID3D12DescriptorHeap_Release(descriptor_heap);
20881     destroy_test_context(&context);
20882 }
20883 
test_uav_load(void)20884 static void test_uav_load(void)
20885 {
20886     struct texture
20887     {
20888         unsigned int width;
20889         unsigned int height;
20890         unsigned int miplevel_count;
20891         unsigned int array_size;
20892         DXGI_FORMAT format;
20893         D3D12_SUBRESOURCE_DATA data[3];
20894     };
20895 
20896     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, rtv_float, rtv_uint, rtv_sint;
20897     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
20898     D3D12_DESCRIPTOR_RANGE descriptor_ranges[1];
20899     ID3D12DescriptorHeap *rtv_heap, *uav_heap;
20900     D3D12_ROOT_PARAMETER root_parameters[2];
20901     const D3D12_SHADER_BYTECODE *current_ps;
20902     ID3D12GraphicsCommandList *command_list;
20903     D3D12_RENDER_TARGET_VIEW_DESC rtv_desc;
20904     const struct texture *current_texture;
20905     D3D12_HEAP_PROPERTIES heap_properties;
20906     ID3D12Resource *texture, *rt_texture;
20907     D3D12_RESOURCE_DESC resource_desc;
20908     D3D12_CLEAR_VALUE clear_value;
20909     struct test_context_desc desc;
20910     struct test_context context;
20911     struct resource_readback rb;
20912     ID3D12CommandQueue *queue;
20913     unsigned int rtv_size;
20914     ID3D12Device *device;
20915     unsigned int i, x, y;
20916     HRESULT hr;
20917 
20918     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
20919     static const DWORD ps_ld_2d_float_code[] =
20920     {
20921 #if 0
20922         RWTexture2D<float> u;
20923 
20924         float main(float4 position : SV_Position) : SV_Target
20925         {
20926             float2 s;
20927             u.GetDimensions(s.x, s.y);
20928             return u[s * float2(position.x / 640.0f, position.y / 480.0f)];
20929         }
20930 #endif
20931         0x43425844, 0xd5996e04, 0x6bede909, 0x0a7ad18e, 0x5eb277fb, 0x00000001, 0x00000194, 0x00000003,
20932         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
20933         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
20934         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
20935         0x00000000, 0x00000e01, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000f8, 0x00000050,
20936         0x0000003e, 0x0100086a, 0x0400189c, 0x0011e000, 0x00000001, 0x00005555, 0x04002064, 0x00101032,
20937         0x00000000, 0x00000001, 0x03000065, 0x00102012, 0x00000000, 0x02000068, 0x00000001, 0x8900003d,
20938         0x800000c2, 0x00155543, 0x00100032, 0x00000000, 0x00004001, 0x00000000, 0x0011ee46, 0x00000001,
20939         0x07000038, 0x001000f2, 0x00000000, 0x00100546, 0x00000000, 0x00101546, 0x00000000, 0x0a000038,
20940         0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x3b088889,
20941         0x3b088889, 0x0500001c, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x890000a3, 0x800000c2,
20942         0x00155543, 0x00100012, 0x00000000, 0x00100e46, 0x00000000, 0x0011ee46, 0x00000001, 0x05000036,
20943         0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e,
20944     };
20945     static const D3D12_SHADER_BYTECODE ps_ld_2d_float = {ps_ld_2d_float_code, sizeof(ps_ld_2d_float_code)};
20946     static const DWORD ps_ld_2d_uint_code[] =
20947     {
20948 #if 0
20949         RWTexture2D<uint> u;
20950 
20951         uint main(float4 position : SV_Position) : SV_Target
20952         {
20953             float2 s;
20954             u.GetDimensions(s.x, s.y);
20955             return u[s * float2(position.x / 640.0f, position.y / 480.0f)];
20956         }
20957 #endif
20958         0x43425844, 0x2cc0af18, 0xb28eca73, 0x9651215b, 0xebe3f361, 0x00000001, 0x00000194, 0x00000003,
20959         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
20960         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
20961         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001,
20962         0x00000000, 0x00000e01, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000f8, 0x00000050,
20963         0x0000003e, 0x0100086a, 0x0400189c, 0x0011e000, 0x00000001, 0x00004444, 0x04002064, 0x00101032,
20964         0x00000000, 0x00000001, 0x03000065, 0x00102012, 0x00000000, 0x02000068, 0x00000001, 0x8900003d,
20965         0x800000c2, 0x00111103, 0x00100032, 0x00000000, 0x00004001, 0x00000000, 0x0011ee46, 0x00000001,
20966         0x07000038, 0x001000f2, 0x00000000, 0x00100546, 0x00000000, 0x00101546, 0x00000000, 0x0a000038,
20967         0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x3b088889,
20968         0x3b088889, 0x0500001c, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x890000a3, 0x800000c2,
20969         0x00111103, 0x00100012, 0x00000000, 0x00100e46, 0x00000000, 0x0011ee46, 0x00000001, 0x05000036,
20970         0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e,
20971     };
20972     static const D3D12_SHADER_BYTECODE ps_ld_2d_uint = {ps_ld_2d_uint_code, sizeof(ps_ld_2d_uint_code)};
20973     static const DWORD ps_ld_2d_int_code[] =
20974     {
20975 #if 0
20976         RWTexture2D<int> u;
20977 
20978         int main(float4 position : SV_Position) : SV_Target
20979         {
20980             float2 s;
20981             u.GetDimensions(s.x, s.y);
20982             return u[s * float2(position.x / 640.0f, position.y / 480.0f)];
20983         }
20984 #endif
20985         0x43425844, 0x7deee248, 0xe7c48698, 0x9454db00, 0x921810e7, 0x00000001, 0x00000194, 0x00000003,
20986         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
20987         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
20988         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000002,
20989         0x00000000, 0x00000e01, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000f8, 0x00000050,
20990         0x0000003e, 0x0100086a, 0x0400189c, 0x0011e000, 0x00000001, 0x00003333, 0x04002064, 0x00101032,
20991         0x00000000, 0x00000001, 0x03000065, 0x00102012, 0x00000000, 0x02000068, 0x00000001, 0x8900003d,
20992         0x800000c2, 0x000cccc3, 0x00100032, 0x00000000, 0x00004001, 0x00000000, 0x0011ee46, 0x00000001,
20993         0x07000038, 0x001000f2, 0x00000000, 0x00100546, 0x00000000, 0x00101546, 0x00000000, 0x0a000038,
20994         0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x3b088889,
20995         0x3b088889, 0x0500001c, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x890000a3, 0x800000c2,
20996         0x000cccc3, 0x00100012, 0x00000000, 0x00100e46, 0x00000000, 0x0011ee46, 0x00000001, 0x05000036,
20997         0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e,
20998     };
20999     static const D3D12_SHADER_BYTECODE ps_ld_2d_int = {ps_ld_2d_int_code, sizeof(ps_ld_2d_int_code)};
21000     static const DWORD ps_ld_2d_uint_arr_code[] =
21001     {
21002 #if 0
21003         RWTexture2DArray<uint> u;
21004 
21005         uint layer;
21006 
21007         uint main(float4 position : SV_Position) : SV_Target
21008         {
21009             float3 s;
21010             u.GetDimensions(s.x, s.y, s.z);
21011             s.z = layer;
21012             return u[s * float3(position.x / 640.0f, position.y / 480.0f, 1.0f)];
21013         }
21014 #endif
21015         0x43425844, 0xa7630358, 0xd7e7228f, 0xa9f1be03, 0x838554f1, 0x00000001, 0x000001bc, 0x00000003,
21016         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
21017         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
21018         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001,
21019         0x00000000, 0x00000e01, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000120, 0x00000050,
21020         0x00000048, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0400409c, 0x0011e000,
21021         0x00000001, 0x00004444, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x00102012,
21022         0x00000000, 0x02000068, 0x00000001, 0x8900003d, 0x80000202, 0x00111103, 0x00100032, 0x00000000,
21023         0x00004001, 0x00000000, 0x0011ee46, 0x00000001, 0x07000038, 0x00100032, 0x00000000, 0x00100046,
21024         0x00000000, 0x00101046, 0x00000000, 0x06000056, 0x001000c2, 0x00000000, 0x00208006, 0x00000000,
21025         0x00000000, 0x0a000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00004002, 0x3acccccd,
21026         0x3b088889, 0x3f800000, 0x3f800000, 0x0500001c, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
21027         0x890000a3, 0x80000202, 0x00111103, 0x00100012, 0x00000000, 0x00100e46, 0x00000000, 0x0011ee46,
21028         0x00000001, 0x05000036, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e,
21029     };
21030     static const D3D12_SHADER_BYTECODE ps_ld_2d_uint_arr = {ps_ld_2d_uint_arr_code, sizeof(ps_ld_2d_uint_arr_code)};
21031     static const float float_data[] =
21032     {
21033          0.50f,  0.25f,  1.00f,  0.00f,
21034         -1.00f, -2.00f, -3.00f, -4.00f,
21035         -0.50f, -0.25f, -1.00f, -0.00f,
21036          1.00f,  2.00f,  3.00f,  4.00f,
21037     };
21038     static const unsigned int uint_data[] =
21039     {
21040         0x00, 0x10, 0x20, 0x30,
21041         0x40, 0x50, 0x60, 0x70,
21042         0x80, 0x90, 0xa0, 0xb0,
21043         0xc0, 0xd0, 0xe0, 0xf0,
21044     };
21045     static const unsigned int uint_data2[] =
21046     {
21047         0xffff, 0xffff, 0xffff, 0xffff,
21048         0xffff, 0xc000, 0xc000, 0xffff,
21049         0xffff, 0xc000, 0xc000, 0xffff,
21050         0xffff, 0xffff, 0xffff, 0xffff,
21051     };
21052     static const unsigned int uint_data3[] =
21053     {
21054         0xaa, 0xaa, 0xcc, 0xcc,
21055         0xaa, 0xaa, 0xdd, 0xdd,
21056         0xbb, 0xbb, 0xee, 0xee,
21057         0xbb, 0xbb, 0xff, 0xff,
21058     };
21059     static const int int_data[] =
21060     {
21061           -1, 0x10, 0x20, 0x30,
21062         0x40, 0x50, 0x60, -777,
21063         -666, 0x90, -555, 0xb0,
21064         0xc0, 0xd0, 0xe0, -101,
21065     };
21066     static const struct texture float_2d = {4, 4, 1, 1, DXGI_FORMAT_R32_FLOAT,
21067             {{float_data, 4 * sizeof(*float_data), 0}}};
21068     static const struct texture uint_2d = {4, 4, 1, 1, DXGI_FORMAT_R32_UINT,
21069             {{uint_data, 4 * sizeof(*uint_data), 0}}};
21070     static const struct texture uint2d_arr = {4, 4, 1, 3, DXGI_FORMAT_R32_UINT,
21071             {{uint_data, 4 * sizeof(*uint_data), 0},
21072             {uint_data2, 4 * sizeof(*uint_data2), 0},
21073             {uint_data3, 4 * sizeof(*uint_data3), 0}}};
21074     static const struct texture int_2d = {4, 4, 1, 1, DXGI_FORMAT_R32_SINT,
21075             {{int_data, 4 * sizeof(*int_data), 0}}};
21076 
21077     static const struct test
21078     {
21079         const D3D12_SHADER_BYTECODE *ps;
21080         const struct texture *texture;
21081         D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
21082         unsigned int constant;
21083         const DWORD *expected_colors;
21084     }
21085     tests[] =
21086     {
21087 #define TEX_2D       D3D12_UAV_DIMENSION_TEXTURE2D
21088 #define TEX_2D_ARRAY D3D12_UAV_DIMENSION_TEXTURE2DARRAY
21089 #define R32_FLOAT    DXGI_FORMAT_R32_FLOAT
21090 #define R32_UINT     DXGI_FORMAT_R32_UINT
21091 #define R32_SINT     DXGI_FORMAT_R32_SINT
21092         {&ps_ld_2d_float,    &float_2d,   {R32_FLOAT, TEX_2D, .Texture2D = {0}}, 0, (const DWORD *)float_data},
21093         {&ps_ld_2d_uint,     &uint_2d,    {R32_UINT,  TEX_2D, .Texture2D = {0}}, 0, (const DWORD *)uint_data},
21094         {&ps_ld_2d_int,      &int_2d,     {R32_SINT,  TEX_2D, .Texture2D = {0}}, 0, (const DWORD *)int_data},
21095 
21096         {&ps_ld_2d_uint_arr, &uint2d_arr, {R32_UINT, TEX_2D_ARRAY, .Texture2DArray = {0, 0, ~0u}}, 0,
21097                 (const DWORD *)uint_data},
21098         {&ps_ld_2d_uint_arr, &uint2d_arr, {R32_UINT, TEX_2D_ARRAY, .Texture2DArray = {0, 0, ~0u}}, 1,
21099                 (const DWORD *)uint_data2},
21100         {&ps_ld_2d_uint_arr, &uint2d_arr, {R32_UINT, TEX_2D_ARRAY, .Texture2DArray = {0, 0, ~0u}}, 2,
21101                 (const DWORD *)uint_data3},
21102         {&ps_ld_2d_uint_arr, &uint2d_arr, {R32_UINT, TEX_2D_ARRAY, .Texture2DArray = {0, 1, ~0u}}, 0,
21103                 (const DWORD *)uint_data2},
21104         {&ps_ld_2d_uint_arr, &uint2d_arr, {R32_UINT, TEX_2D_ARRAY, .Texture2DArray = {0, 1, ~0u}}, 1,
21105                 (const DWORD *)uint_data3},
21106         {&ps_ld_2d_uint_arr, &uint2d_arr, {R32_UINT, TEX_2D_ARRAY, .Texture2DArray = {0, 2, ~0u}}, 0,
21107                 (const DWORD *)uint_data3},
21108 #undef TEX_2D
21109 #undef TEX_2D_ARRAY
21110 #undef R32_FLOAT
21111 #undef R32_UINT
21112 #undef R32_SINT
21113     };
21114 
21115     memset(&desc, 0, sizeof(desc));
21116     desc.no_render_target = true;
21117     if (!init_test_context(&context, &desc))
21118         return;
21119     device = context.device;
21120     command_list = context.list;
21121     queue = context.queue;
21122 
21123     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
21124     descriptor_ranges[0].NumDescriptors = 1;
21125     descriptor_ranges[0].BaseShaderRegister = 1;
21126     descriptor_ranges[0].RegisterSpace = 0;
21127     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
21128     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
21129     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
21130     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
21131     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
21132     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
21133     root_parameters[1].Constants.ShaderRegister = 0;
21134     root_parameters[1].Constants.RegisterSpace = 0;
21135     root_parameters[1].Constants.Num32BitValues = 1;
21136     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
21137     root_signature_desc.NumParameters = 2;
21138     root_signature_desc.pParameters = root_parameters;
21139     root_signature_desc.NumStaticSamplers = 0;
21140     root_signature_desc.pStaticSamplers = NULL;
21141     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
21142     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
21143     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
21144 
21145     set_viewport(&context.viewport, 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 1.0f);
21146     set_rect(&context.scissor_rect, 0, 0, 640, 480);
21147 
21148     memset(&heap_properties, 0, sizeof(heap_properties));
21149     heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
21150     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
21151     resource_desc.Alignment = 0;
21152     resource_desc.Width = 640;
21153     resource_desc.Height = 480;
21154     resource_desc.DepthOrArraySize = 1;
21155     resource_desc.MipLevels = 1;
21156     resource_desc.Format = DXGI_FORMAT_R32_TYPELESS;
21157     resource_desc.SampleDesc.Count = 1;
21158     resource_desc.SampleDesc.Quality = 0;
21159     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
21160     resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
21161     clear_value.Format = DXGI_FORMAT_R32_FLOAT;
21162     clear_value.Color[0] = 1.0f;
21163     clear_value.Color[1] = 1.0f;
21164     clear_value.Color[2] = 1.0f;
21165     clear_value.Color[3] = 1.0f;
21166     hr = ID3D12Device_CreateCommittedResource(device,
21167             &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
21168             D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
21169             &IID_ID3D12Resource, (void **)&rt_texture);
21170     ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
21171 
21172     rtv_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 3);
21173     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rtv_heap);
21174     rtv_size = ID3D12Device_GetDescriptorHandleIncrementSize(device,
21175             D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
21176 
21177     memset(&rtv_desc, 0, sizeof(rtv_desc));
21178     rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
21179     rtv_desc.Format = DXGI_FORMAT_R32_FLOAT;
21180     ID3D12Device_CreateRenderTargetView(device, rt_texture, &rtv_desc, cpu_handle);
21181     rtv_float = cpu_handle;
21182     cpu_handle.ptr += rtv_size;
21183 
21184     rtv_desc.Format = DXGI_FORMAT_R32_UINT;
21185     ID3D12Device_CreateRenderTargetView(device, rt_texture, &rtv_desc, cpu_handle);
21186     rtv_uint = cpu_handle;
21187     cpu_handle.ptr += rtv_size;
21188 
21189     rtv_desc.Format = DXGI_FORMAT_R32_SINT;
21190     ID3D12Device_CreateRenderTargetView(device, rt_texture, &rtv_desc, cpu_handle);
21191     rtv_sint = cpu_handle;
21192 
21193     uav_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
21194 
21195     resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
21196 
21197     texture = NULL;
21198     current_ps = NULL;
21199     current_texture = NULL;
21200     for (i = 0; i < ARRAY_SIZE(tests); ++i)
21201     {
21202         const struct test *test = &tests[i];
21203 
21204         if (current_ps != test->ps)
21205         {
21206             if (context.pipeline_state)
21207                 ID3D12PipelineState_Release(context.pipeline_state);
21208             current_ps = tests[i].ps;
21209             context.pipeline_state = create_pipeline_state(context.device,
21210                     context.root_signature, test->uav_desc.Format, NULL, current_ps, NULL);
21211         }
21212 
21213         if (current_texture != test->texture)
21214         {
21215             if (texture)
21216                 ID3D12Resource_Release(texture);
21217 
21218             current_texture = test->texture;
21219 
21220             resource_desc.Width = current_texture->width;
21221             resource_desc.Height = current_texture->height;
21222             resource_desc.MipLevels = current_texture->miplevel_count;
21223             resource_desc.DepthOrArraySize = current_texture->array_size;
21224             resource_desc.Format = current_texture->format;
21225             hr = ID3D12Device_CreateCommittedResource(device,
21226                     &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
21227                     D3D12_RESOURCE_STATE_COPY_DEST, NULL,
21228                     &IID_ID3D12Resource, (void **)&texture);
21229             ok(SUCCEEDED(hr), "Test %u: Failed to create texture, hr %#x.\n", i, hr);
21230 
21231             upload_texture_data(texture, current_texture->data,
21232                     resource_desc.MipLevels * resource_desc.DepthOrArraySize, queue, command_list);
21233             reset_command_list(command_list, context.allocator);
21234 
21235             transition_resource_state(command_list, texture,
21236                     D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21237         }
21238 
21239         cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(uav_heap);
21240         ID3D12Device_CreateUnorderedAccessView(device, texture, NULL, &test->uav_desc, cpu_handle);
21241 
21242         switch (test->uav_desc.Format)
21243         {
21244             default:
21245                 trace("Unhandled format %#x.\n", test->uav_desc.Format);
21246                 /* fall-through */
21247             case DXGI_FORMAT_R32_FLOAT:
21248                 cpu_handle = rtv_float;
21249                 break;
21250             case DXGI_FORMAT_R32_UINT:
21251                 cpu_handle = rtv_uint;
21252                 break;
21253             case DXGI_FORMAT_R32_SINT:
21254                 cpu_handle = rtv_sint;
21255                 break;
21256         }
21257 
21258         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
21259         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
21260         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
21261         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
21262         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &uav_heap);
21263         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
21264                 ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(uav_heap));
21265         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(command_list, 1, test->constant, 0);
21266         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
21267         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &cpu_handle, false, NULL);
21268         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, cpu_handle, white, 0, NULL);
21269         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
21270 
21271         transition_sub_resource_state(command_list, rt_texture, 0,
21272                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
21273 
21274         get_texture_readback_with_command_list(rt_texture, 0, &rb, queue, command_list);
21275         for (y = 0; y < 4; ++y)
21276         {
21277             for (x = 0; x < 4; ++x)
21278             {
21279                 unsigned int expected = test->expected_colors[y * 4 + x];
21280                 unsigned int color = get_readback_uint(&rb, 80 + x * 160, 60 + y * 120, 0);
21281                 ok(compare_color(color, expected, 0),
21282                         "Test %u: Got 0x%08x, expected 0x%08x at (%u, %u).\n",
21283                         i, color, expected, x, y);
21284             }
21285         }
21286         release_resource_readback(&rb);
21287 
21288         reset_command_list(command_list, context.allocator);
21289         transition_sub_resource_state(command_list, rt_texture, 0,
21290                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
21291     }
21292     ID3D12Resource_Release(texture);
21293 
21294     ID3D12DescriptorHeap_Release(rtv_heap);
21295     ID3D12DescriptorHeap_Release(uav_heap);
21296     ID3D12Resource_Release(rt_texture);
21297     destroy_test_context(&context);
21298 }
21299 
test_cs_uav_store(void)21300 static void test_cs_uav_store(void)
21301 {
21302     D3D12_CPU_DESCRIPTOR_HANDLE cpu_descriptor_handle;
21303     D3D12_GPU_DESCRIPTOR_HANDLE gpu_descriptor_handle;
21304     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
21305     const D3D12_SHADER_BYTECODE *current_shader;
21306     D3D12_DESCRIPTOR_RANGE descriptor_ranges[1];
21307     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
21308     ID3D12DescriptorHeap *cpu_descriptor_heap;
21309     ID3D12GraphicsCommandList *command_list;
21310     D3D12_ROOT_PARAMETER root_parameters[2];
21311     ID3D12DescriptorHeap *descriptor_heap;
21312     ID3D12RootSignature *root_signature;
21313     ID3D12PipelineState *pipeline_state;
21314     struct resource_readback rb;
21315     struct test_context context;
21316     ID3D12CommandQueue *queue;
21317     ID3D12Resource *resource;
21318     ID3D12Device *device;
21319     ID3D12Resource *cb;
21320     struct vec4 input;
21321     unsigned int i;
21322     HRESULT hr;
21323     RECT rect;
21324 
21325     static const DWORD cs_1_thread_code[] =
21326     {
21327 #if 0
21328         RWTexture2D<float> u;
21329 
21330         float value;
21331 
21332         [numthreads(1, 1, 1)]
21333         void main()
21334         {
21335             uint x, y, width, height;
21336             u.GetDimensions(width, height);
21337             for (y = 0; y < height; ++y)
21338             {
21339                 for (x = 0; x < width; ++x)
21340                     u[uint2(x, y)] = value;
21341             }
21342         }
21343 #endif
21344         0x43425844, 0x6503503a, 0x4cd524e6, 0x2473915d, 0x93cf1201, 0x00000001, 0x000001c8, 0x00000003,
21345         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
21346         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000174, 0x00050050, 0x0000005d, 0x0100086a,
21347         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0400189c, 0x0011e000, 0x00000000, 0x00005555,
21348         0x02000068, 0x00000003, 0x0400009b, 0x00000001, 0x00000001, 0x00000001, 0x8900103d, 0x800000c2,
21349         0x00155543, 0x00100032, 0x00000000, 0x00004001, 0x00000000, 0x0011ee46, 0x00000000, 0x05000036,
21350         0x00100042, 0x00000000, 0x00004001, 0x00000000, 0x01000030, 0x07000050, 0x00100082, 0x00000000,
21351         0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x03040003, 0x0010003a, 0x00000000, 0x05000036,
21352         0x001000e2, 0x00000001, 0x00100aa6, 0x00000000, 0x05000036, 0x00100082, 0x00000000, 0x00004001,
21353         0x00000000, 0x01000030, 0x07000050, 0x00100012, 0x00000002, 0x0010003a, 0x00000000, 0x0010000a,
21354         0x00000000, 0x03040003, 0x0010000a, 0x00000002, 0x05000036, 0x00100012, 0x00000001, 0x0010003a,
21355         0x00000000, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46, 0x00000001, 0x00208006, 0x00000000,
21356         0x00000000, 0x0700001e, 0x00100082, 0x00000000, 0x0010003a, 0x00000000, 0x00004001, 0x00000001,
21357         0x01000016, 0x0700001e, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x00004001, 0x00000001,
21358         0x01000016, 0x0100003e,
21359     };
21360     static const D3D12_SHADER_BYTECODE cs_1_thread = {cs_1_thread_code, sizeof(cs_1_thread_code)};
21361     static const DWORD cs_1_group_code[] =
21362     {
21363 #if 0
21364         RWTexture2D<float> u;
21365 
21366         float value;
21367 
21368         [numthreads(16, 16, 1)]
21369         void main(uint3 threadID : SV_GroupThreadID)
21370         {
21371             uint2 count, size ;
21372             u.GetDimensions(size.x, size.y);
21373             count = size / (uint2)16;
21374             for (uint y = 0; y < count.y; ++y)
21375                 for (uint x = 0; x < count.x; ++x)
21376                     u[count * threadID.xy + uint2(x, y)] = value;
21377         }
21378 #endif
21379         0x43425844, 0x9fb86044, 0x352c196d, 0x92e14094, 0x46bb95a7, 0x00000001, 0x00000218, 0x00000003,
21380         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
21381         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000001c4, 0x00050050, 0x00000071, 0x0100086a,
21382         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0400189c, 0x0011e000, 0x00000000, 0x00005555,
21383         0x0200005f, 0x00022032, 0x02000068, 0x00000004, 0x0400009b, 0x00000010, 0x00000010, 0x00000001,
21384         0x8900103d, 0x800000c2, 0x00155543, 0x00100032, 0x00000000, 0x00004001, 0x00000000, 0x0011ee46,
21385         0x00000000, 0x0a000055, 0x001000f2, 0x00000000, 0x00100546, 0x00000000, 0x00004002, 0x00000004,
21386         0x00000004, 0x00000004, 0x00000004, 0x05000036, 0x00100012, 0x00000001, 0x00004001, 0x00000000,
21387         0x01000030, 0x07000050, 0x00100022, 0x00000001, 0x0010000a, 0x00000001, 0x0010003a, 0x00000000,
21388         0x03040003, 0x0010001a, 0x00000001, 0x05000036, 0x001000e2, 0x00000002, 0x00100006, 0x00000001,
21389         0x05000036, 0x00100022, 0x00000001, 0x00004001, 0x00000000, 0x01000030, 0x07000050, 0x00100042,
21390         0x00000001, 0x0010001a, 0x00000001, 0x0010000a, 0x00000000, 0x03040003, 0x0010002a, 0x00000001,
21391         0x05000036, 0x00100012, 0x00000002, 0x0010001a, 0x00000001, 0x08000023, 0x001000f2, 0x00000003,
21392         0x00100e46, 0x00000000, 0x00022546, 0x00100e46, 0x00000002, 0x080000a4, 0x0011e0f2, 0x00000000,
21393         0x00100e46, 0x00000003, 0x00208006, 0x00000000, 0x00000000, 0x0700001e, 0x00100022, 0x00000001,
21394         0x0010001a, 0x00000001, 0x00004001, 0x00000001, 0x01000016, 0x0700001e, 0x00100012, 0x00000001,
21395         0x0010000a, 0x00000001, 0x00004001, 0x00000001, 0x01000016, 0x0100003e,
21396     };
21397     static const D3D12_SHADER_BYTECODE cs_1_group = {cs_1_group_code, sizeof(cs_1_group_code)};
21398     static const DWORD cs_1_store_code[] =
21399     {
21400 #if 0
21401         RWTexture2D<float> u;
21402 
21403         float value;
21404 
21405         [numthreads(1, 1, 1)]
21406         void main(uint3 groupID : SV_GroupID)
21407         {
21408             u[groupID.xy] = value;
21409         }
21410 #endif
21411         0x43425844, 0xc3add41b, 0x67df51b1, 0x2b887930, 0xcb1ee991, 0x00000001, 0x000000b8, 0x00000003,
21412         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
21413         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000064, 0x00050050, 0x00000019, 0x0100086a,
21414         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0400189c, 0x0011e000, 0x00000000, 0x00005555,
21415         0x0200005f, 0x00021032, 0x0400009b, 0x00000001, 0x00000001, 0x00000001, 0x070000a4, 0x0011e0f2,
21416         0x00000000, 0x00021546, 0x00208006, 0x00000000, 0x00000000, 0x0100003e,
21417     };
21418     static const D3D12_SHADER_BYTECODE cs_1_store = {cs_1_store_code, sizeof(cs_1_store_code)};
21419     static const DWORD cs_dispatch_id_code[] =
21420     {
21421 #if 0
21422         RWTexture2D<float> u;
21423 
21424         float value;
21425 
21426         [numthreads(4, 4, 1)]
21427         void main(uint3 id : SV_DispatchThreadID)
21428         {
21429             u[id.xy] = value;
21430         }
21431 #endif
21432         0x43425844, 0x60166991, 0x4b595266, 0x7fb67d79, 0x485c4f0d, 0x00000001, 0x000000b8, 0x00000003,
21433         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
21434         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000064, 0x00050050, 0x00000019, 0x0100086a,
21435         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0400189c, 0x0011e000, 0x00000000, 0x00005555,
21436         0x0200005f, 0x00020032, 0x0400009b, 0x00000004, 0x00000004, 0x00000001, 0x070000a4, 0x0011e0f2,
21437         0x00000000, 0x00020546, 0x00208006, 0x00000000, 0x00000000, 0x0100003e,
21438     };
21439     static const D3D12_SHADER_BYTECODE cs_dispatch_id = {cs_dispatch_id_code, sizeof(cs_dispatch_id_code)};
21440     static const DWORD cs_group_index_code[] =
21441     {
21442 #if 0
21443         RWTexture2D<float> u;
21444 
21445         float value;
21446 
21447         [numthreads(32, 1, 1)]
21448         void main(uint index : SV_GroupIndex)
21449         {
21450             uint2 size;
21451             u.GetDimensions(size.x, size.y);
21452             uint count = size.x * size.y / 32;
21453             index *= count;
21454             for (uint i = 0; i < count; ++i, ++index)
21455                 u[uint2(index % size.x, index / size.x)] = value;
21456         }
21457 #endif
21458         0x43425844, 0xb685a70f, 0x94c2f263, 0x4f1d8eaa, 0xeab65731, 0x00000001, 0x000001f8, 0x00000003,
21459         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
21460         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000001a4, 0x00050050, 0x00000069, 0x0100086a,
21461         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0400189c, 0x0011e000, 0x00000000, 0x00005555,
21462         0x0200005f, 0x00024000, 0x02000068, 0x00000004, 0x0400009b, 0x00000020, 0x00000001, 0x00000001,
21463         0x8900103d, 0x800000c2, 0x00155543, 0x00100032, 0x00000000, 0x00004001, 0x00000000, 0x0011ee46,
21464         0x00000000, 0x08000026, 0x0000d000, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x0010001a,
21465         0x00000000, 0x07000055, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x00000005,
21466         0x07000026, 0x0000d000, 0x00100042, 0x00000000, 0x0002400a, 0x0010001a, 0x00000000, 0x05000036,
21467         0x00100012, 0x00000001, 0x0010002a, 0x00000000, 0x05000036, 0x00100022, 0x00000001, 0x00004001,
21468         0x00000000, 0x01000030, 0x07000050, 0x00100082, 0x00000000, 0x0010001a, 0x00000001, 0x0010001a,
21469         0x00000000, 0x03040003, 0x0010003a, 0x00000000, 0x0900004e, 0x00100012, 0x00000002, 0x00100012,
21470         0x00000003, 0x0010000a, 0x00000001, 0x0010000a, 0x00000000, 0x05000036, 0x001000e2, 0x00000003,
21471         0x00100006, 0x00000002, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46, 0x00000003, 0x00208006,
21472         0x00000000, 0x00000000, 0x0a00001e, 0x00100032, 0x00000001, 0x00100046, 0x00000001, 0x00004002,
21473         0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x01000016, 0x0100003e,
21474     };
21475     static const D3D12_SHADER_BYTECODE cs_group_index = {cs_group_index_code, sizeof(cs_group_index_code)};
21476     static const float zero[4] = {0};
21477     static const struct
21478     {
21479         const D3D12_SHADER_BYTECODE *shader;
21480         float value;
21481     }
21482     tests[] =
21483     {
21484         {&cs_1_thread,    1.0f},
21485         {&cs_1_thread,    0.5f},
21486         {&cs_1_group,     2.0f},
21487         {&cs_1_group,     4.0f},
21488         {&cs_group_index, 0.3f},
21489         {&cs_group_index, 0.1f},
21490     };
21491 
21492     if (!init_compute_test_context(&context))
21493         return;
21494     device = context.device;
21495     command_list = context.list;
21496     queue = context.queue;
21497 
21498     cb = create_upload_buffer(context.device, sizeof(input), NULL);
21499 
21500     resource = create_default_texture(device, 64, 64, DXGI_FORMAT_R32_FLOAT,
21501             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
21502 
21503     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
21504     descriptor_ranges[0].NumDescriptors = 1;
21505     descriptor_ranges[0].BaseShaderRegister = 0;
21506     descriptor_ranges[0].RegisterSpace = 0;
21507     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
21508     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
21509     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
21510     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
21511     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
21512     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
21513     root_parameters[1].Descriptor.ShaderRegister = 0;
21514     root_parameters[1].Descriptor.RegisterSpace = 0;
21515     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
21516     root_signature_desc.NumParameters = 2;
21517     root_signature_desc.pParameters = root_parameters;
21518     root_signature_desc.NumStaticSamplers = 0;
21519     root_signature_desc.pStaticSamplers = NULL;
21520     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
21521     hr = create_root_signature(device, &root_signature_desc, &root_signature);
21522     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
21523 
21524     descriptor_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
21525     cpu_descriptor_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
21526     cpu_descriptor_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(descriptor_heap);
21527     gpu_descriptor_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap);
21528 
21529     uav_desc.Format = DXGI_FORMAT_R32_FLOAT;
21530     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
21531     uav_desc.Texture2D.MipSlice = 0;
21532     uav_desc.Texture2D.PlaneSlice = 0;
21533     ID3D12Device_CreateUnorderedAccessView(device, resource, NULL, &uav_desc, cpu_descriptor_handle);
21534     cpu_descriptor_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cpu_descriptor_heap);
21535     ID3D12Device_CreateUnorderedAccessView(device, resource, NULL, &uav_desc, cpu_descriptor_handle);
21536 
21537     hr = ID3D12GraphicsCommandList_Close(command_list);
21538     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
21539 
21540     current_shader = NULL;
21541     pipeline_state = NULL;
21542     for (i = 0; i < ARRAY_SIZE(tests); ++i)
21543     {
21544         vkd3d_test_set_context("Test %u", i);
21545 
21546         if (current_shader != tests[i].shader)
21547         {
21548             if (pipeline_state)
21549                 ID3D12PipelineState_Release(pipeline_state);
21550 
21551             current_shader = tests[i].shader;
21552             pipeline_state = create_compute_pipeline_state(device, root_signature, *current_shader);
21553         }
21554 
21555         memset(&input, 0, sizeof(input));
21556         input.x = tests[i].value;
21557         update_buffer_data(cb, 0, sizeof(input), &input.x);
21558 
21559         reset_command_list(command_list, context.allocator);
21560         transition_sub_resource_state(command_list, resource, 0,
21561                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21562 
21563         ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(command_list,
21564                 gpu_descriptor_handle, cpu_descriptor_handle, resource, zero, 0, NULL);
21565 
21566         ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
21567         ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, root_signature);
21568         ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(command_list, 1,
21569                 ID3D12Resource_GetGPUVirtualAddress(cb));
21570         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
21571         ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_descriptor_handle);
21572         ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
21573 
21574         transition_sub_resource_state(command_list, resource, 0,
21575                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
21576         check_sub_resource_float(resource, 0, queue, command_list, tests[i].value, 2);
21577     }
21578     vkd3d_test_set_context(NULL);
21579 
21580     ID3D12PipelineState_Release(pipeline_state);
21581     pipeline_state = create_compute_pipeline_state(device, root_signature, cs_1_store);
21582 
21583     memset(&input, 0, sizeof(input));
21584     input.x = 1.0f;
21585     update_buffer_data(cb, 0, sizeof(input), &input.x);
21586 
21587     reset_command_list(command_list, context.allocator);
21588     transition_sub_resource_state(command_list, resource, 0,
21589             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21590 
21591     ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(command_list,
21592             gpu_descriptor_handle, cpu_descriptor_handle, resource, zero, 0, NULL);
21593     ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
21594     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, root_signature);
21595     ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(command_list, 1,
21596             ID3D12Resource_GetGPUVirtualAddress(cb));
21597     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
21598     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_descriptor_handle);
21599     ID3D12GraphicsCommandList_Dispatch(command_list, 64, 64, 1);
21600 
21601     transition_sub_resource_state(command_list, resource, 0,
21602             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
21603     check_sub_resource_float(resource, 0, queue, command_list, 1.0f, 2);
21604 
21605     memset(&input, 0, sizeof(input));
21606     input.x = 0.5f;
21607     update_buffer_data(cb, 0, sizeof(input), &input.x);
21608 
21609     reset_command_list(command_list, context.allocator);
21610     transition_sub_resource_state(command_list, resource, 0,
21611             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21612 
21613     ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
21614     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, root_signature);
21615     ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(command_list, 1,
21616             ID3D12Resource_GetGPUVirtualAddress(cb));
21617     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
21618     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_descriptor_handle);
21619     ID3D12GraphicsCommandList_Dispatch(command_list, 16, 32, 1);
21620 
21621     transition_sub_resource_state(command_list, resource, 0,
21622             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
21623     get_texture_readback_with_command_list(resource, 0, &rb, queue, command_list);
21624     set_rect(&rect, 0, 0, 16, 32);
21625     check_readback_data_float(&rb, &rect, 0.5f, 2);
21626     set_rect(&rect, 0, 32, rb.width, rb.height);
21627     check_readback_data_float(&rb, &rect, 1.0f, 2);
21628     set_rect(&rect, 16, 0, rb.width, rb.height);
21629     check_readback_data_float(&rb, &rect, 1.0f, 2);
21630     release_resource_readback(&rb);
21631 
21632     ID3D12PipelineState_Release(pipeline_state);
21633     pipeline_state = create_compute_pipeline_state(device, root_signature, cs_dispatch_id);
21634 
21635     memset(&input, 0, sizeof(input));
21636     input.x = 0.6f;
21637     update_buffer_data(cb, 0, sizeof(input), &input.x);
21638 
21639     reset_command_list(command_list, context.allocator);
21640     transition_sub_resource_state(command_list, resource, 0,
21641             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21642 
21643     ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
21644     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, root_signature);
21645     ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(command_list, 1,
21646             ID3D12Resource_GetGPUVirtualAddress(cb));
21647     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
21648     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_descriptor_handle);
21649     ID3D12GraphicsCommandList_Dispatch(command_list, 15, 15, 1);
21650 
21651     transition_sub_resource_state(command_list, resource, 0,
21652             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
21653     get_texture_readback_with_command_list(resource, 0, &rb, queue, command_list);
21654     set_rect(&rect, 0, 0, 60, 60);
21655     check_readback_data_float(&rb, &rect, 0.6f, 2);
21656     set_rect(&rect, 0, 60, rb.width, rb.height);
21657     check_readback_data_float(&rb, &rect, 1.0f, 2);
21658     set_rect(&rect, 60, 0, rb.width, rb.height);
21659     check_readback_data_float(&rb, &rect, 1.0f, 2);
21660     release_resource_readback(&rb);
21661 
21662     memset(&input, 0, sizeof(input));
21663     input.x = 0.7f;
21664     update_buffer_data(cb, 0, sizeof(input), &input.x);
21665 
21666     reset_command_list(command_list, context.allocator);
21667     transition_sub_resource_state(command_list, resource, 0,
21668             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21669 
21670     ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
21671     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, root_signature);
21672     ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(command_list, 1,
21673             ID3D12Resource_GetGPUVirtualAddress(cb));
21674     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
21675     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0, gpu_descriptor_handle);
21676     ID3D12GraphicsCommandList_Dispatch(command_list, 16, 16, 1);
21677 
21678     transition_sub_resource_state(command_list, resource, 0,
21679             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
21680     check_sub_resource_float(resource, 0, queue, command_list, 0.7f, 2);
21681 
21682     ID3D12Resource_Release(cb);
21683     ID3D12Resource_Release(resource);
21684     ID3D12PipelineState_Release(pipeline_state);
21685     ID3D12RootSignature_Release(root_signature);
21686     ID3D12DescriptorHeap_Release(cpu_descriptor_heap);
21687     ID3D12DescriptorHeap_Release(descriptor_heap);
21688     destroy_test_context(&context);
21689 }
21690 
read_uav_counter(const struct test_context * context,ID3D12Resource * counter_buffer,size_t offset)21691 static unsigned int read_uav_counter(const struct test_context *context,
21692         ID3D12Resource *counter_buffer, size_t offset)
21693 {
21694     struct resource_readback rb;
21695     uint32_t counter;
21696 
21697     transition_sub_resource_state(context->list, counter_buffer, 0,
21698             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
21699     get_buffer_readback_with_command_list(counter_buffer, DXGI_FORMAT_R32_UINT, &rb,
21700             context->queue, context->list);
21701     counter = get_readback_uint(&rb, offset / sizeof(counter), 0, 0);
21702     release_resource_readback(&rb);
21703     reset_command_list(context->list, context->allocator);
21704     transition_sub_resource_state(context->list, counter_buffer, 0,
21705             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21706     return counter;
21707 }
21708 
compare_id(const void * a,const void * b)21709 static int compare_id(const void *a, const void *b)
21710 {
21711     return *(int *)a - *(int *)b;
21712 }
21713 
test_uav_counters(void)21714 static void test_uav_counters(void)
21715 {
21716     ID3D12Resource *buffer, *out_buffer, *counter_buffer;
21717     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
21718     D3D12_DESCRIPTOR_RANGE descriptor_ranges[1];
21719     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
21720     ID3D12GraphicsCommandList *command_list;
21721     D3D12_ROOT_PARAMETER root_parameters[1];
21722     ID3D12DescriptorHeap *descriptor_heap;
21723     struct resource_readback rb;
21724     struct test_context context;
21725     ID3D12CommandQueue *queue;
21726     uint32_t data, id[128];
21727     ID3D12Device *device;
21728     uint32_t counter;
21729     unsigned int i;
21730     HRESULT hr;
21731 
21732     static const DWORD cs_producer_code[] =
21733     {
21734 #if 0
21735         RWStructuredBuffer<uint> u;
21736 
21737         [numthreads(4, 1, 1)]
21738         void main(uint3 dispatch_id : SV_DispatchThreadID)
21739         {
21740             uint counter = u.IncrementCounter();
21741             u[counter] = dispatch_id.x;
21742         }
21743 #endif
21744         0x43425844, 0x013163a8, 0xe7d371b8, 0x4f71e39a, 0xd479e584, 0x00000001, 0x000000c8, 0x00000003,
21745         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
21746         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000074, 0x00050050, 0x0000001d, 0x0100086a,
21747         0x0480009e, 0x0011e000, 0x00000000, 0x00000004, 0x0200005f, 0x00020012, 0x02000068, 0x00000001,
21748         0x0400009b, 0x00000004, 0x00000001, 0x00000001, 0x050000b2, 0x00100012, 0x00000000, 0x0011e000,
21749         0x00000000, 0x080000a8, 0x0011e012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000000,
21750         0x0002000a, 0x0100003e,
21751     };
21752     static const DWORD cs_consumer_code[] =
21753     {
21754 #if 0
21755         RWStructuredBuffer<uint> u;
21756         RWStructuredBuffer<uint> u2;
21757 
21758         [numthreads(4, 1, 1)]
21759         void main()
21760         {
21761             uint counter = u.DecrementCounter();
21762             u2[counter] = u[counter];
21763         }
21764 #endif
21765         0x43425844, 0x957ef3dd, 0x9f317559, 0x09c8f12d, 0xdbfd98c8, 0x00000001, 0x00000100, 0x00000003,
21766         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
21767         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000ac, 0x00050050, 0x0000002b, 0x0100086a,
21768         0x0480009e, 0x0011e000, 0x00000000, 0x00000004, 0x0400009e, 0x0011e000, 0x00000001, 0x00000004,
21769         0x02000068, 0x00000001, 0x0400009b, 0x00000004, 0x00000001, 0x00000001, 0x050000b3, 0x00100012,
21770         0x00000000, 0x0011e000, 0x00000000, 0x8b0000a7, 0x80002302, 0x00199983, 0x00100022, 0x00000000,
21771         0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x0011e006, 0x00000000, 0x090000a8, 0x0011e012,
21772         0x00000001, 0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x0010001a, 0x00000000, 0x0100003e,
21773     };
21774 
21775     if (!init_compute_test_context(&context))
21776         return;
21777     device = context.device;
21778     command_list = context.list;
21779     queue = context.queue;
21780 
21781     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
21782     descriptor_ranges[0].NumDescriptors = 2;
21783     descriptor_ranges[0].BaseShaderRegister = 0;
21784     descriptor_ranges[0].RegisterSpace = 0;
21785     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
21786     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
21787     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
21788     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
21789     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
21790     root_signature_desc.NumParameters = 1;
21791     root_signature_desc.pParameters = root_parameters;
21792     root_signature_desc.NumStaticSamplers = 0;
21793     root_signature_desc.pStaticSamplers = NULL;
21794     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
21795     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
21796     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
21797 
21798     context.pipeline_state = create_compute_pipeline_state(device, context.root_signature,
21799             shader_bytecode(cs_producer_code, sizeof(cs_producer_code)));
21800 
21801     descriptor_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 3);
21802 
21803     buffer = create_default_buffer(device, 1024,
21804             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21805     out_buffer = create_default_buffer(device, 1024,
21806             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21807     counter_buffer = create_default_buffer(device, 1024,
21808             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
21809 
21810     memset(&uav_desc, 0, sizeof(uav_desc));
21811     uav_desc.Format = DXGI_FORMAT_UNKNOWN;
21812     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
21813     uav_desc.Buffer.NumElements = 256;
21814     uav_desc.Buffer.StructureByteStride = sizeof(uint32_t);
21815     uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
21816     ID3D12Device_CreateUnorderedAccessView(device, buffer, counter_buffer, &uav_desc,
21817             get_cpu_descriptor_handle(&context, descriptor_heap, 0));
21818     ID3D12Device_CreateUnorderedAccessView(device, out_buffer, NULL, &uav_desc,
21819             get_cpu_descriptor_handle(&context, descriptor_heap, 1));
21820 
21821     counter = 0;
21822     upload_buffer_data(counter_buffer, 0, sizeof(counter), &counter, queue, command_list);
21823     reset_command_list(command_list, context.allocator);
21824     transition_sub_resource_state(command_list, counter_buffer, 0,
21825             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21826 
21827     /* produce */
21828     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
21829     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
21830     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
21831     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0,
21832             ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap));
21833     ID3D12GraphicsCommandList_Dispatch(command_list, 16, 1, 1);
21834 
21835     counter = read_uav_counter(&context, counter_buffer, 0);
21836     ok(counter == 64, "Got unexpected value %u.\n", counter);
21837     transition_sub_resource_state(command_list, buffer, 0,
21838             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
21839     get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
21840     memcpy(id, rb.data, 64 * sizeof(*id));
21841     release_resource_readback(&rb);
21842     qsort(id, 64, sizeof(*id), compare_id);
21843     for (i = 0; i < 64; ++i)
21844     {
21845         if (id[i] != i)
21846             break;
21847     }
21848     ok(i == 64, "Got unexpected id %u at %u.\n", id[i], i);
21849 
21850     reset_command_list(command_list, context.allocator);
21851     transition_sub_resource_state(command_list, buffer, 0,
21852             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21853 
21854     ID3D12PipelineState_Release(context.pipeline_state);
21855     context.pipeline_state = create_compute_pipeline_state(device, context.root_signature,
21856             shader_bytecode(cs_consumer_code, sizeof(cs_consumer_code)));
21857 
21858     /* consume */
21859     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
21860     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
21861     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
21862     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0,
21863             ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap));
21864     ID3D12GraphicsCommandList_Dispatch(command_list, 16, 1, 1);
21865 
21866     transition_sub_resource_state(command_list, out_buffer, 0,
21867             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
21868     counter = read_uav_counter(&context, counter_buffer, 0);
21869     ok(!counter, "Got unexpected value %u.\n", counter);
21870     get_buffer_readback_with_command_list(out_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
21871     memcpy(id, rb.data, 64 * sizeof(*id));
21872     release_resource_readback(&rb);
21873     qsort(id, 64, sizeof(*id), compare_id);
21874     for (i = 0; i < 64; ++i)
21875     {
21876         if (id[i] != i)
21877             break;
21878     }
21879     ok(i == 64, "Got unexpected id %u at %u.\n", id[i], i);
21880 
21881     reset_command_list(command_list, context.allocator);
21882     transition_sub_resource_state(command_list, counter_buffer, 0,
21883             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
21884     transition_sub_resource_state(command_list, buffer, 0,
21885             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
21886     transition_sub_resource_state(command_list, out_buffer, 0,
21887             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21888 
21889     /* produce on CPU */
21890     counter = 8;
21891     for (i = 0; i < counter; ++i)
21892         id[i] = 0xdeadbeef;
21893     upload_buffer_data(buffer, 0, counter * sizeof(*id), id, queue, command_list);
21894     reset_command_list(command_list, context.allocator);
21895     upload_buffer_data(counter_buffer, 0, sizeof(counter), &counter, queue, command_list);
21896     reset_command_list(command_list, context.allocator);
21897 
21898     transition_sub_resource_state(command_list, counter_buffer, 0,
21899             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21900     transition_sub_resource_state(command_list, buffer, 0,
21901             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
21902 
21903     /* consume */
21904     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
21905     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
21906     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
21907     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0,
21908             ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap));
21909     ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
21910     ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
21911 
21912     transition_sub_resource_state(command_list, out_buffer, 0,
21913             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
21914     counter = read_uav_counter(&context, counter_buffer, 0);
21915     ok(!counter, "Got unexpected value %u.\n", counter);
21916 
21917     get_buffer_readback_with_command_list(out_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
21918     for (i = 0; i < 8; ++i)
21919     {
21920         data = get_readback_uint(&rb, i, 0, 0);
21921         ok(data == 0xdeadbeef, "Got data %u at %u.\n", data, i);
21922     }
21923     release_resource_readback(&rb);
21924 
21925     ID3D12Resource_Release(buffer);
21926     ID3D12Resource_Release(out_buffer);
21927     ID3D12Resource_Release(counter_buffer);
21928     ID3D12DescriptorHeap_Release(descriptor_heap);
21929     destroy_test_context(&context);
21930 }
21931 
test_decrement_uav_counter(void)21932 static void test_decrement_uav_counter(void)
21933 {
21934     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
21935     D3D12_DESCRIPTOR_RANGE descriptor_ranges[1];
21936     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
21937     ID3D12Resource *buffer, *counter_buffer;
21938     ID3D12GraphicsCommandList *command_list;
21939     D3D12_ROOT_PARAMETER root_parameters[1];
21940     ID3D12DescriptorHeap *descriptor_heap;
21941     struct test_context context;
21942     ID3D12CommandQueue *queue;
21943     ID3D12Device *device;
21944     uint32_t counter;
21945     unsigned int i;
21946     HRESULT hr;
21947 
21948     static const DWORD cs_code[] =
21949     {
21950 #if 0
21951         RWStructuredBuffer<uint> u;
21952 
21953         [numthreads(1, 1, 1)]
21954         void main()
21955         {
21956             InterlockedMin(u[0], u.DecrementCounter());
21957         }
21958 #endif
21959         0x43425844, 0xceb0e9d3, 0x64ea7417, 0xbd37d26f, 0x589c63c2, 0x00000001, 0x000000c8, 0x00000003,
21960         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
21961         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000074, 0x00050050, 0x0000001d, 0x0100086a,
21962         0x0480009e, 0x0011e000, 0x00000000, 0x00000004, 0x02000068, 0x00000001, 0x0400009b, 0x00000001,
21963         0x00000001, 0x00000001, 0x050000b3, 0x00100012, 0x00000000, 0x0011e000, 0x00000000, 0x0a0000b1,
21964         0x0011e000, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0010000a,
21965         0x00000000, 0x0100003e,
21966     };
21967     static const struct
21968     {
21969         uint32_t initial_value;
21970         unsigned int decrement_count;
21971         uint32_t expected_value;
21972         uint32_t expected_min_value;
21973     }
21974     tests[] =
21975     {
21976         {0x00000000,  1, 0xffffffff, 0xffffffff},
21977         {0x00000001,  1, 0x00000000, 0x00000000},
21978         {0xffffffff,  1, 0xfffffffe, 0xfffffffe},
21979         {0x00000010, 16, 0x00000000, 0x00000000},
21980         {0x00000010, 17, 0xffffffff, 0x00000000},
21981     };
21982 
21983     if (!init_compute_test_context(&context))
21984         return;
21985     device = context.device;
21986     command_list = context.list;
21987     queue = context.queue;
21988 
21989     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
21990     descriptor_ranges[0].NumDescriptors = 1;
21991     descriptor_ranges[0].BaseShaderRegister = 0;
21992     descriptor_ranges[0].RegisterSpace = 0;
21993     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
21994     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
21995     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
21996     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
21997     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
21998     root_signature_desc.NumParameters = 1;
21999     root_signature_desc.pParameters = root_parameters;
22000     root_signature_desc.NumStaticSamplers = 0;
22001     root_signature_desc.pStaticSamplers = NULL;
22002     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
22003     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
22004     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
22005 
22006     context.pipeline_state = create_compute_pipeline_state(device, context.root_signature,
22007             shader_bytecode(cs_code, sizeof(cs_code)));
22008 
22009     descriptor_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
22010 
22011     buffer = create_default_buffer(device, 1024,
22012             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
22013     counter_buffer = create_default_buffer(device, 1024,
22014             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
22015 
22016     memset(&uav_desc, 0, sizeof(uav_desc));
22017     uav_desc.Format = DXGI_FORMAT_UNKNOWN;
22018     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
22019     uav_desc.Buffer.NumElements = 256;
22020     uav_desc.Buffer.StructureByteStride = sizeof(uint32_t);
22021     uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
22022     ID3D12Device_CreateUnorderedAccessView(device, buffer, counter_buffer, &uav_desc,
22023             get_cpu_descriptor_handle(&context, descriptor_heap, 0));
22024 
22025     for (i = 0; i < ARRAY_SIZE(tests); ++i)
22026     {
22027         vkd3d_test_set_context("Test %u", i);
22028 
22029         transition_sub_resource_state(command_list, buffer, 0,
22030                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
22031         counter = 0xffffffff;
22032         upload_buffer_data(buffer, 0, sizeof(counter), &counter, queue, command_list);
22033         reset_command_list(command_list, context.allocator);
22034         transition_sub_resource_state(command_list, buffer, 0,
22035                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
22036 
22037         transition_sub_resource_state(command_list, counter_buffer, 0,
22038                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
22039         counter = tests[i].initial_value;
22040         upload_buffer_data(counter_buffer, 0, sizeof(counter), &counter, queue, command_list);
22041         reset_command_list(command_list, context.allocator);
22042         transition_sub_resource_state(command_list, counter_buffer, 0,
22043                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
22044 
22045         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
22046         ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
22047         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
22048         ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list, 0,
22049                 ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap));
22050         ID3D12GraphicsCommandList_Dispatch(command_list, tests[i].decrement_count, 1, 1);
22051 
22052         counter = read_uav_counter(&context, counter_buffer, 0);
22053         ok(counter == tests[i].expected_value, "Got %u, expected %u.\n",
22054                 counter, tests[i].expected_value);
22055 
22056         counter = read_uav_counter(&context, buffer, 0);
22057         ok(counter == tests[i].expected_min_value, "Got %u, expected %u.\n",
22058                 counter, tests[i].expected_min_value);
22059     }
22060     vkd3d_test_set_context(NULL);
22061 
22062     ID3D12Resource_Release(buffer);
22063     ID3D12Resource_Release(counter_buffer);
22064     ID3D12DescriptorHeap_Release(descriptor_heap);
22065     destroy_test_context(&context);
22066 }
22067 
test_atomic_instructions(void)22068 static void test_atomic_instructions(void)
22069 {
22070     ID3D12Resource *ps_buffer, *cs_buffer, *cs_buffer2;
22071     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
22072     ID3D12GraphicsCommandList *command_list;
22073     D3D12_ROOT_PARAMETER root_parameters[3];
22074     ID3D12PipelineState *pipeline_state;
22075     struct test_context_desc desc;
22076     struct resource_readback rb;
22077     struct test_context context;
22078     ID3D12CommandQueue *queue;
22079     ID3D12Device *device;
22080     unsigned int i, j;
22081     bool is_todo;
22082     HRESULT hr;
22083 
22084     static const DWORD ps_atomics_code[] =
22085     {
22086 #if 0
22087         RWByteAddressBuffer u;
22088 
22089         uint4 v;
22090         int4 i;
22091 
22092         void main()
22093         {
22094             u.InterlockedAnd(0 * 4, v.x);
22095             u.InterlockedCompareStore(1 * 4, v.y, v.x);
22096             u.InterlockedAdd(2 * 4, v.x);
22097             u.InterlockedOr(3 * 4, v.x);
22098             u.InterlockedMax(4 * 4, i.x);
22099             u.InterlockedMin(5 * 4, i.x);
22100             u.InterlockedMax(6 * 4, v.x);
22101             u.InterlockedMin(7 * 4, v.x);
22102             u.InterlockedXor(8 * 4, v.x);
22103         }
22104 #endif
22105         0x43425844, 0x24c6a30c, 0x2ce4437d, 0xdee8a0df, 0xd18cb4bc, 0x00000001, 0x000001ac, 0x00000003,
22106         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
22107         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000158, 0x00000050, 0x00000056, 0x0100086a,
22108         0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0300009d, 0x0011e000, 0x00000000, 0x080000a9,
22109         0x0011e000, 0x00000000, 0x00004001, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0b0000ac,
22110         0x0011e000, 0x00000000, 0x00004001, 0x00000004, 0x0020801a, 0x00000000, 0x00000000, 0x0020800a,
22111         0x00000000, 0x00000000, 0x080000ad, 0x0011e000, 0x00000000, 0x00004001, 0x00000008, 0x0020800a,
22112         0x00000000, 0x00000000, 0x080000aa, 0x0011e000, 0x00000000, 0x00004001, 0x0000000c, 0x0020800a,
22113         0x00000000, 0x00000000, 0x080000ae, 0x0011e000, 0x00000000, 0x00004001, 0x00000010, 0x0020800a,
22114         0x00000000, 0x00000001, 0x080000af, 0x0011e000, 0x00000000, 0x00004001, 0x00000014, 0x0020800a,
22115         0x00000000, 0x00000001, 0x080000b0, 0x0011e000, 0x00000000, 0x00004001, 0x00000018, 0x0020800a,
22116         0x00000000, 0x00000000, 0x080000b1, 0x0011e000, 0x00000000, 0x00004001, 0x0000001c, 0x0020800a,
22117         0x00000000, 0x00000000, 0x080000ab, 0x0011e000, 0x00000000, 0x00004001, 0x00000020, 0x0020800a,
22118         0x00000000, 0x00000000, 0x0100003e,
22119     };
22120     static const D3D12_SHADER_BYTECODE ps_atomics = {ps_atomics_code, sizeof(ps_atomics_code)};
22121     static const DWORD cs_atomics_code[] =
22122     {
22123 #if 0
22124         RWByteAddressBuffer u;
22125         RWByteAddressBuffer u2;
22126 
22127         uint4 v;
22128         int4 i;
22129 
22130         [numthreads(1, 1, 1)]
22131         void main()
22132         {
22133             uint r;
22134             u.InterlockedAnd(0 * 4, v.x, r);
22135             u2.Store(0 * 4, r);
22136             u.InterlockedCompareExchange(1 * 4, v.y, v.x, r);
22137             u2.Store(1 * 4, r);
22138             u.InterlockedAdd(2 * 4, v.x, r);
22139             u2.Store(2 * 4, r);
22140             u.InterlockedOr(3 * 4, v.x, r);
22141             u2.Store(3 * 4, r);
22142             u.InterlockedMax(4 * 4, i.x, r);
22143             u2.Store(4 * 4, r);
22144             u.InterlockedMin(5 * 4, i.x, r);
22145             u2.Store(5 * 4, r);
22146             u.InterlockedMax(6 * 4, v.x, r);
22147             u2.Store(6 * 4, r);
22148             u.InterlockedMin(7 * 4, v.x, r);
22149             u2.Store(7 * 4, r);
22150             u.InterlockedXor(8 * 4, v.x, r);
22151             u2.Store(8 * 4, r);
22152         }
22153 #endif
22154         0x43425844, 0x859a96e3, 0x1a35e463, 0x1e89ce58, 0x5cfe430a, 0x00000001, 0x0000026c, 0x00000003,
22155         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
22156         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000218, 0x00050050, 0x00000086, 0x0100086a,
22157         0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0300009d, 0x0011e000, 0x00000000, 0x0300009d,
22158         0x0011e000, 0x00000001, 0x02000068, 0x00000001, 0x0400009b, 0x00000001, 0x00000001, 0x00000001,
22159         0x0a0000b5, 0x00100012, 0x00000000, 0x0011e000, 0x00000000, 0x00004001, 0x00000000, 0x0020800a,
22160         0x00000000, 0x00000000, 0x0d0000b9, 0x00100022, 0x00000000, 0x0011e000, 0x00000000, 0x00004001,
22161         0x00000004, 0x0020801a, 0x00000000, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0a0000b4,
22162         0x00100042, 0x00000000, 0x0011e000, 0x00000000, 0x00004001, 0x00000008, 0x0020800a, 0x00000000,
22163         0x00000000, 0x0a0000b6, 0x00100082, 0x00000000, 0x0011e000, 0x00000000, 0x00004001, 0x0000000c,
22164         0x0020800a, 0x00000000, 0x00000000, 0x070000a6, 0x0011e0f2, 0x00000001, 0x00004001, 0x00000000,
22165         0x00100e46, 0x00000000, 0x0a0000ba, 0x00100012, 0x00000000, 0x0011e000, 0x00000000, 0x00004001,
22166         0x00000010, 0x0020800a, 0x00000000, 0x00000001, 0x0a0000bb, 0x00100022, 0x00000000, 0x0011e000,
22167         0x00000000, 0x00004001, 0x00000014, 0x0020800a, 0x00000000, 0x00000001, 0x0a0000bc, 0x00100042,
22168         0x00000000, 0x0011e000, 0x00000000, 0x00004001, 0x00000018, 0x0020800a, 0x00000000, 0x00000000,
22169         0x0a0000bd, 0x00100082, 0x00000000, 0x0011e000, 0x00000000, 0x00004001, 0x0000001c, 0x0020800a,
22170         0x00000000, 0x00000000, 0x070000a6, 0x0011e0f2, 0x00000001, 0x00004001, 0x00000010, 0x00100e46,
22171         0x00000000, 0x0a0000b7, 0x00100012, 0x00000000, 0x0011e000, 0x00000000, 0x00004001, 0x00000020,
22172         0x0020800a, 0x00000000, 0x00000000, 0x070000a6, 0x0011e012, 0x00000001, 0x00004001, 0x00000020,
22173         0x0010000a, 0x00000000, 0x0100003e,
22174     };
22175     static D3D12_SHADER_BYTECODE cs_atomics = {cs_atomics_code, sizeof(cs_atomics_code)};
22176     static const char * const instructions[] =
22177     {
22178         "atomic_and", "atomic_cmp_store", "atomic_iadd", "atomic_or",
22179         "atomic_imax", "atomic_imin", "atomic_umax", "atomic_umin", "atomic_xor",
22180     };
22181     static const char * const imm_instructions[] =
22182     {
22183         "imm_atomic_and", "imm_atomic_cmp_exch", "imm_atomic_iadd", "imm_atomic_or",
22184         "imm_atomic_imax", "imm_atomic_imin", "imm_atomic_umax", "imm_atomic_umin", "imm_atomic_xor",
22185     };
22186     static const struct test
22187     {
22188         struct uvec4 v;
22189         struct ivec4 i;
22190         unsigned int input[ARRAY_SIZE(instructions)];
22191         unsigned int expected_result[ARRAY_SIZE(instructions)];
22192     }
22193     tests[] =
22194     {
22195         {{ 1,   0 }, {-1}, {0xffff,   0, 1, 0, 0, 0, 0, 0, 0xff }, {     1,   1, 2,   1, 0, ~0u, 1,  0, 0xfe}},
22196         {{~0u, ~0u}, { 0}, {0xffff, 0xf, 1, 0, 0, 0, 0, 9,   ~0u}, {0xffff, 0xf, 0, ~0u, 0,  0, ~0u, 9,    0}},
22197     };
22198 
22199     memset(&desc, 0, sizeof(desc));
22200     desc.rt_width = 1;
22201     desc.rt_height = 1;
22202     desc.rt_format = DXGI_FORMAT_R32_FLOAT;
22203     desc.no_root_signature = true;
22204     if (!init_test_context(&context, &desc))
22205         return;
22206     device = context.device;
22207     command_list = context.list;
22208     queue = context.queue;
22209 
22210     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
22211     root_parameters[0].Descriptor.ShaderRegister = 0;
22212     root_parameters[0].Descriptor.RegisterSpace = 0;
22213     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
22214     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
22215     root_parameters[1].Descriptor.ShaderRegister = 1;
22216     root_parameters[1].Descriptor.RegisterSpace = 0;
22217     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
22218     root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
22219     root_parameters[2].Constants.ShaderRegister = 0;
22220     root_parameters[2].Constants.RegisterSpace = 0;
22221     root_parameters[2].Constants.Num32BitValues = 8;
22222     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
22223     root_signature_desc.NumParameters = 3;
22224     root_signature_desc.pParameters = root_parameters;
22225     root_signature_desc.NumStaticSamplers = 0;
22226     root_signature_desc.pStaticSamplers = NULL;
22227     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
22228     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
22229     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
22230 
22231     ps_buffer = create_default_buffer(device, sizeof(tests->input),
22232             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
22233     cs_buffer = create_default_buffer(device, sizeof(tests->input),
22234             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
22235     cs_buffer2 = create_default_buffer(device, sizeof(tests->input),
22236             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
22237 
22238     context.pipeline_state = create_pipeline_state(context.device, context.root_signature, 0, NULL, &ps_atomics, NULL);
22239 
22240     pipeline_state = create_compute_pipeline_state(device, context.root_signature, cs_atomics);
22241 
22242     for (i = 0; i < ARRAY_SIZE(tests); ++i)
22243     {
22244         const struct test *test = &tests[i];
22245 
22246         upload_buffer_data(ps_buffer, 0, sizeof(test->input), test->input, queue, command_list);
22247         reset_command_list(command_list, context.allocator);
22248 
22249         upload_buffer_data(cs_buffer, 0, sizeof(test->input), test->input, queue, command_list);
22250         reset_command_list(command_list, context.allocator);
22251 
22252         transition_sub_resource_state(command_list, ps_buffer, 0,
22253                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
22254         transition_sub_resource_state(command_list, cs_buffer, 0,
22255                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
22256         transition_sub_resource_state(command_list, cs_buffer2, 0,
22257                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
22258 
22259         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
22260         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
22261         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
22262         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
22263         ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView(command_list,
22264                 0, ID3D12Resource_GetGPUVirtualAddress(ps_buffer));
22265         ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView(command_list,
22266                 1, ID3D12Resource_GetGPUVirtualAddress(cs_buffer));
22267         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 2, 4, &test->v, 0);
22268         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 2, 4, &test->i, 4);
22269 
22270         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
22271         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
22272 
22273         ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
22274         ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list,
22275                 0, ID3D12Resource_GetGPUVirtualAddress(cs_buffer));
22276         ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list,
22277                 1, ID3D12Resource_GetGPUVirtualAddress(cs_buffer2));
22278         ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(command_list, 2, 4, &test->v, 0);
22279         ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(command_list, 2, 4, &test->i, 4);
22280 
22281         ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
22282         ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
22283 
22284         transition_sub_resource_state(command_list, ps_buffer, 0,
22285                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
22286         get_buffer_readback_with_command_list(ps_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
22287         for (j = 0; j < ARRAY_SIZE(instructions); ++j)
22288         {
22289             unsigned int value = get_readback_uint(&rb, j, 0, 0);
22290             unsigned int expected = test->expected_result[j];
22291 
22292             is_todo = test->i.x < 0
22293                     && (!strcmp(instructions[j], "atomic_imax") || !strcmp(instructions[j], "atomic_imin"));
22294 
22295             bug_if(is_todo && is_nvidia_device(device))
22296             todo_if(is_todo)
22297             ok(value == expected, "Test %u: Got %#x (%d), expected %#x (%d) for '%s' "
22298                     "with inputs (%u, %u), (%d), %#x (%d).\n",
22299                     i, value, value, expected, expected, instructions[j],
22300                     test->v.x, test->v.y, test->i.x, test->input[j], test->input[j]);
22301         }
22302         release_resource_readback(&rb);
22303         reset_command_list(command_list, context.allocator);
22304 
22305         transition_sub_resource_state(command_list, cs_buffer, 0,
22306                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
22307         get_buffer_readback_with_command_list(cs_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
22308         for (j = 0; j < ARRAY_SIZE(instructions); ++j)
22309         {
22310             bool todo_instruction = !strcmp(imm_instructions[j], "imm_atomic_imax")
22311                     || !strcmp(imm_instructions[j], "imm_atomic_imin");
22312             unsigned int value = get_readback_uint(&rb, j, 0, 0);
22313             unsigned int expected = test->expected_result[j];
22314 
22315             bug_if(test->i.x < 0 && todo_instruction && is_nvidia_device(device))
22316             todo_if(test->i.x < 0 && todo_instruction)
22317             ok(value == expected, "Test %u: Got %#x (%d), expected %#x (%d) for '%s' "
22318                     "with inputs (%u, %u), (%d), %#x (%d).\n",
22319                     i, value, value, expected, expected, imm_instructions[j],
22320                     test->v.x, test->v.y, test->i.x, test->input[j], test->input[j]);
22321         }
22322         release_resource_readback(&rb);
22323         reset_command_list(command_list, context.allocator);
22324 
22325         transition_sub_resource_state(command_list, cs_buffer2, 0,
22326                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
22327         get_buffer_readback_with_command_list(cs_buffer2, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
22328         for (j = 0; j < ARRAY_SIZE(instructions); ++j)
22329         {
22330             unsigned int out_value = get_readback_uint(&rb, j, 0, 0);
22331             ok(out_value == test->input[j], "Got original value %u, expected %u for '%s'.\n",
22332                     out_value, test->input[j], imm_instructions[j]);
22333         }
22334         release_resource_readback(&rb);
22335         reset_command_list(command_list, context.allocator);
22336 
22337         transition_sub_resource_state(command_list, ps_buffer, 0,
22338                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_COPY_DEST);
22339         transition_sub_resource_state(command_list, cs_buffer, 0,
22340                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_COPY_DEST);
22341         transition_sub_resource_state(command_list, cs_buffer2, 0,
22342                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_COPY_DEST);
22343     }
22344 
22345     ID3D12Resource_Release(ps_buffer);
22346     ID3D12Resource_Release(cs_buffer);
22347     ID3D12Resource_Release(cs_buffer2);
22348     ID3D12PipelineState_Release(pipeline_state);
22349     destroy_test_context(&context);
22350 }
22351 
test_buffer_srv(void)22352 static void test_buffer_srv(void)
22353 {
22354     struct buffer
22355     {
22356         unsigned int byte_count;
22357         unsigned int data_offset;
22358         const void *data;
22359         unsigned int structure_byte_stride;
22360     };
22361 
22362     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
22363     const D3D12_SHADER_BYTECODE *current_shader;
22364     D3D12_DESCRIPTOR_RANGE descriptor_ranges[1];
22365     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
22366     ID3D12GraphicsCommandList *command_list;
22367     D3D12_ROOT_PARAMETER root_parameters[2];
22368     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
22369     D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
22370     ID3D12DescriptorHeap *descriptor_heap;
22371     const struct buffer *current_buffer;
22372     unsigned int color, expected_color;
22373     struct test_context_desc desc;
22374     struct test_context context;
22375     struct resource_readback rb;
22376     ID3D12CommandQueue *queue;
22377     ID3D12Resource *buffer;
22378     ID3D12Device *device;
22379     unsigned int i, x, y;
22380     HRESULT hr;
22381 
22382     static const DWORD ps_float4_code[] =
22383     {
22384 #if 0
22385         Buffer<float4> b;
22386 
22387         float2 size;
22388 
22389         float4 main(float4 position : SV_POSITION) : SV_Target
22390         {
22391             float2 p;
22392             int2 coords;
22393             p.x = position.x / 640.0f;
22394             p.y = position.y / 480.0f;
22395             coords = int2(p.x * size.x, p.y * size.y);
22396             return b.Load(coords.y * size.x + coords.x);
22397         }
22398 #endif
22399         0x43425844, 0xf10ea650, 0x311f5c38, 0x3a888b7f, 0x58230334, 0x00000001, 0x000001a0, 0x00000003,
22400         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
22401         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
22402         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
22403         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000104, 0x00000040,
22404         0x00000041, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04000858, 0x00107000, 0x00000000,
22405         0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
22406         0x02000068, 0x00000001, 0x08000038, 0x00100032, 0x00000000, 0x00101516, 0x00000000, 0x00208516,
22407         0x00000000, 0x00000000, 0x0a000038, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00004002,
22408         0x3b088889, 0x3acccccd, 0x00000000, 0x00000000, 0x05000043, 0x00100032, 0x00000000, 0x00100046,
22409         0x00000000, 0x0a000032, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0020800a, 0x00000000,
22410         0x00000000, 0x0010001a, 0x00000000, 0x0500001b, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
22411         0x0700002d, 0x001020f2, 0x00000000, 0x00100006, 0x00000000, 0x00107e46, 0x00000000, 0x0100003e,
22412     };
22413     static const D3D12_SHADER_BYTECODE ps_float4 = {ps_float4_code, sizeof(ps_float4_code)};
22414     static const DWORD ps_structured_code[] =
22415     {
22416 #if 0
22417         StructuredBuffer<float4> b;
22418 
22419         float2 size;
22420 
22421         float4 main(float4 position : SV_POSITION) : SV_Target
22422         {
22423             float2 p;
22424             int2 coords;
22425             p.x = position.x / 640.0f;
22426             p.y = position.y / 480.0f;
22427             coords = int2(p.x * size.x, p.y * size.y);
22428             return b[coords.y * size.x + coords.x];
22429         }
22430 #endif
22431         0x43425844, 0x246caabb, 0xf1e7d6b9, 0xcbe720dc, 0xcdc23036, 0x00000001, 0x000001c0, 0x00000004,
22432         0x00000030, 0x00000064, 0x00000098, 0x000001b0, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008,
22433         0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f,
22434         0x004e4f49, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
22435         0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000110,
22436         0x00000040, 0x00000044, 0x0100486a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x040000a2,
22437         0x00107000, 0x00000000, 0x00000010, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065,
22438         0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x08000038, 0x00100032, 0x00000000, 0x00101516,
22439         0x00000000, 0x00208516, 0x00000000, 0x00000000, 0x0a000038, 0x00100032, 0x00000000, 0x00100046,
22440         0x00000000, 0x00004002, 0x3b088889, 0x3acccccd, 0x00000000, 0x00000000, 0x05000043, 0x00100032,
22441         0x00000000, 0x00100046, 0x00000000, 0x0a000032, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
22442         0x0020800a, 0x00000000, 0x00000000, 0x0010001a, 0x00000000, 0x0500001c, 0x00100012, 0x00000000,
22443         0x0010000a, 0x00000000, 0x090000a7, 0x001020f2, 0x00000000, 0x0010000a, 0x00000000, 0x00004001,
22444         0x00000000, 0x00107e46, 0x00000000, 0x0100003e, 0x30494653, 0x00000008, 0x00000002, 0x00000000,
22445     };
22446     static const D3D12_SHADER_BYTECODE ps_structured = {ps_structured_code, sizeof(ps_structured_code)};
22447     static const unsigned int rgba16[] =
22448     {
22449         0xff0000ff, 0xff00ffff, 0xff00ff00, 0xffffff00,
22450         0xffff0000, 0xffff00ff, 0xff000000, 0xff7f7f7f,
22451         0xffffffff, 0xffffffff, 0xffffffff, 0xff000000,
22452         0xffffffff, 0xff000000, 0xff000000, 0xff000000,
22453     };
22454     static const unsigned int rgba4[] =
22455     {
22456         0xffffffff, 0xff0000ff,
22457         0xff000000, 0xff00ff00,
22458     };
22459     static const BYTE r4[] =
22460     {
22461         0xde, 0xad,
22462         0xba, 0xbe,
22463     };
22464     static const struct vec4 rgba_float[] =
22465     {
22466         {1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f},
22467         {0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 0.0f, 1.0f},
22468     };
22469     static const struct buffer rgba16_buffer = {sizeof(rgba16), 0, &rgba16};
22470     static const struct buffer rgba16_offset_buffer = {256 + sizeof(rgba16), 256, &rgba16};
22471     static const struct buffer rgba4_buffer  = {sizeof(rgba4), 0, &rgba4};
22472     static const struct buffer r4_buffer = {sizeof(r4), 0, &r4};
22473     static const struct buffer r4_offset_buffer = {256 + sizeof(r4), 256, &r4};
22474     static const struct buffer float_buffer = {sizeof(rgba_float), 0, &rgba_float, sizeof(*rgba_float)};
22475     static const struct buffer float_offset_buffer = {256 + sizeof(rgba_float), 256,
22476             &rgba_float, sizeof(*rgba_float)};
22477     static const unsigned int rgba16_colors2x2[] =
22478     {
22479         0xff0000ff, 0xff0000ff, 0xff00ffff, 0xff00ffff,
22480         0xff0000ff, 0xff0000ff, 0xff00ffff, 0xff00ffff,
22481         0xff00ff00, 0xff00ff00, 0xffffff00, 0xffffff00,
22482         0xff00ff00, 0xff00ff00, 0xffffff00, 0xffffff00,
22483     };
22484     static const unsigned int rgba16_colors1x1[] =
22485     {
22486         0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
22487         0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
22488         0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
22489         0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff,
22490     };
22491     static const unsigned int rgba4_colors[] =
22492     {
22493         0xffffffff, 0xffffffff, 0xff0000ff, 0xff0000ff,
22494         0xffffffff, 0xffffffff, 0xff0000ff, 0xff0000ff,
22495         0xff000000, 0xff000000, 0xff00ff00, 0xff00ff00,
22496         0xff000000, 0xff000000, 0xff00ff00, 0xff00ff00,
22497     };
22498     static const unsigned int r4_colors[] =
22499     {
22500         0xff0000de, 0xff0000de, 0xff0000ad, 0xff0000ad,
22501         0xff0000de, 0xff0000de, 0xff0000ad, 0xff0000ad,
22502         0xff0000ba, 0xff0000ba, 0xff0000be, 0xff0000be,
22503         0xff0000ba, 0xff0000ba, 0xff0000be, 0xff0000be,
22504     };
22505     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
22506 
22507     static const struct test
22508     {
22509         const D3D12_SHADER_BYTECODE *shader;
22510         const struct buffer *buffer;
22511         DXGI_FORMAT srv_format;
22512         unsigned int srv_first_element;
22513         unsigned int srv_element_count;
22514         struct vec2 size;
22515         const unsigned int *expected_colors;
22516     }
22517     tests[] =
22518     {
22519         {&ps_float4,     &rgba16_buffer,        DXGI_FORMAT_R8G8B8A8_UNORM,   0, 16, {4.0f, 4.0f}, rgba16},
22520         {&ps_float4,     &rgba16_offset_buffer, DXGI_FORMAT_R8G8B8A8_UNORM,  64, 16, {4.0f, 4.0f}, rgba16},
22521         {&ps_float4,     &rgba16_buffer,        DXGI_FORMAT_R8G8B8A8_UNORM,   0,  4, {2.0f, 2.0f}, rgba16_colors2x2},
22522         {&ps_float4,     &rgba16_buffer,        DXGI_FORMAT_R8G8B8A8_UNORM,   0,  1, {1.0f, 1.0f}, rgba16_colors1x1},
22523         {&ps_float4,     &rgba4_buffer,         DXGI_FORMAT_R8G8B8A8_UNORM,   0,  4, {2.0f, 2.0f}, rgba4_colors},
22524         {&ps_float4,     &r4_buffer,            DXGI_FORMAT_R8_UNORM,         0,  4, {2.0f, 2.0f}, r4_colors},
22525         {&ps_float4,     &r4_offset_buffer,     DXGI_FORMAT_R8_UNORM,       256,  4, {2.0f, 2.0f}, r4_colors},
22526         {&ps_structured, &float_buffer,         DXGI_FORMAT_UNKNOWN,          0,  4, {2.0f, 2.0f}, rgba4_colors},
22527         {&ps_structured, &float_offset_buffer,  DXGI_FORMAT_UNKNOWN,         16,  4, {2.0f, 2.0f}, rgba4_colors},
22528     };
22529 
22530     memset(&desc, 0, sizeof(desc));
22531     desc.rt_width = 640;
22532     desc.rt_height = 480;
22533     desc.no_root_signature = true;
22534     if (!init_test_context(&context, &desc))
22535         return;
22536     device = context.device;
22537     command_list = context.list;
22538     queue = context.queue;
22539 
22540     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
22541     descriptor_ranges[0].NumDescriptors = 1;
22542     descriptor_ranges[0].BaseShaderRegister = 0;
22543     descriptor_ranges[0].RegisterSpace = 0;
22544     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
22545     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
22546     root_parameters[0].DescriptorTable.NumDescriptorRanges = 1;
22547     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
22548     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
22549     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
22550     root_parameters[1].Constants.ShaderRegister = 0;
22551     root_parameters[1].Constants.RegisterSpace = 0;
22552     root_parameters[1].Constants.Num32BitValues = 2;
22553     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
22554     root_signature_desc.NumParameters = 2;
22555     root_signature_desc.pParameters = root_parameters;
22556     root_signature_desc.NumStaticSamplers = 0;
22557     root_signature_desc.pStaticSamplers = NULL;
22558     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
22559     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
22560     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
22561 
22562     descriptor_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
22563     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(descriptor_heap);
22564     gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap);
22565 
22566     buffer = NULL;
22567     current_shader = NULL;
22568     current_buffer = NULL;
22569     for (i = 0; i < ARRAY_SIZE(tests); ++i)
22570     {
22571         const struct test *test = &tests[i];
22572 
22573         vkd3d_test_set_context("Test %u", i);
22574 
22575         if (current_shader != test->shader)
22576         {
22577             if (context.pipeline_state)
22578                 ID3D12PipelineState_Release(context.pipeline_state);
22579             current_shader = tests[i].shader;
22580             context.pipeline_state = create_pipeline_state(context.device,
22581                     context.root_signature, context.render_target_desc.Format,
22582                     NULL, current_shader, NULL);
22583         }
22584 
22585         if (current_buffer != test->buffer)
22586         {
22587             if (buffer)
22588                 ID3D12Resource_Release(buffer);
22589 
22590             current_buffer = test->buffer;
22591 
22592             buffer = create_default_buffer(device, current_buffer->byte_count,
22593                     D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
22594 
22595             upload_buffer_data(buffer, current_buffer->data_offset,
22596                     current_buffer->byte_count - current_buffer->data_offset,
22597                     current_buffer->data, queue, command_list);
22598             reset_command_list(command_list, context.allocator);
22599 
22600             transition_sub_resource_state(command_list, buffer, 0,
22601                     D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
22602         }
22603 
22604         memset(&srv_desc, 0, sizeof(srv_desc));
22605         srv_desc.Format = test->srv_format;
22606         srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
22607         srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
22608         srv_desc.Buffer.FirstElement = test->srv_first_element;
22609         srv_desc.Buffer.NumElements = test->srv_element_count;
22610         srv_desc.Buffer.StructureByteStride = current_buffer->structure_byte_stride;
22611         ID3D12Device_CreateShaderResourceView(device, buffer, &srv_desc, cpu_handle);
22612 
22613         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
22614 
22615         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
22616         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
22617         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
22618         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
22619         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
22620         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
22621         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &descriptor_heap);
22622         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
22623         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 2, &test->size.x, 0);
22624         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
22625 
22626         transition_sub_resource_state(command_list, context.render_target, 0,
22627                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
22628 
22629         get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
22630         for (y = 0; y < 4; ++y)
22631         {
22632             for (x = 0; x < 4; ++x)
22633             {
22634                 color = get_readback_uint(&rb, 80 + x * 160, 60 + y * 120, 0);
22635                 expected_color = test->expected_colors[y * 4 + x];
22636                 ok(compare_color(color, expected_color, 1),
22637                         "Test %u: Got 0x%08x, expected 0x%08x at (%u, %u).\n",
22638                         i, color, expected_color, x, y);
22639             }
22640         }
22641         release_resource_readback(&rb);
22642 
22643         reset_command_list(command_list, context.allocator);
22644         transition_sub_resource_state(command_list, context.render_target, 0,
22645                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
22646     }
22647     vkd3d_test_set_context(NULL);
22648 
22649     ID3D12DescriptorHeap_Release(descriptor_heap);
22650     ID3D12Resource_Release(buffer);
22651     destroy_test_context(&context);
22652 }
22653 
test_create_query_heap(void)22654 static void test_create_query_heap(void)
22655 {
22656     ID3D12Device *device;
22657     D3D12_QUERY_HEAP_DESC heap_desc;
22658     ID3D12QueryHeap *query_heap;
22659     ULONG refcount;
22660     HRESULT hr;
22661     int i;
22662 
22663     static const D3D12_QUERY_HEAP_TYPE types[] =
22664     {
22665         D3D12_QUERY_HEAP_TYPE_OCCLUSION,
22666         D3D12_QUERY_HEAP_TYPE_TIMESTAMP,
22667         D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS,
22668     };
22669 
22670     if (!(device = create_device()))
22671     {
22672         skip("Failed to create device.\n");
22673         return;
22674     }
22675 
22676     for (i = 0; i < ARRAY_SIZE(types); ++i)
22677     {
22678         heap_desc.Type = types[i];
22679         heap_desc.Count = 1;
22680         heap_desc.NodeMask = 0;
22681 
22682         hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
22683         ok(hr == S_OK, "Failed to create query heap, type %u, hr %#x.\n", types[i], hr);
22684 
22685         ID3D12QueryHeap_Release(query_heap);
22686     }
22687 
22688     heap_desc.Type = D3D12_QUERY_HEAP_TYPE_SO_STATISTICS;
22689     heap_desc.Count = 1;
22690     heap_desc.NodeMask = 0;
22691 
22692     hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
22693     if (hr != E_NOTIMPL)
22694     {
22695         ok(hr == S_OK, "Failed to create query heap, type %u, hr %#x.\n", heap_desc.Type, hr);
22696         ID3D12QueryHeap_Release(query_heap);
22697     }
22698     else
22699     {
22700         skip("Stream output is not supported.\n");
22701     }
22702 
22703     refcount = ID3D12Device_Release(device);
22704     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
22705 }
22706 
test_query_timestamp(void)22707 static void test_query_timestamp(void)
22708 {
22709     uint64_t timestamps[4], timestamp_frequency, timestamp_diff, time_diff;
22710     ID3D12GraphicsCommandList *command_list;
22711     D3D12_QUERY_HEAP_DESC heap_desc;
22712     struct test_context_desc desc;
22713     ID3D12QueryHeap *query_heap;
22714     struct resource_readback rb;
22715     struct test_context context;
22716     time_t time_start, time_end;
22717     ID3D12CommandQueue *queue;
22718     ID3D12Resource *resource;
22719     ID3D12Device *device;
22720     unsigned int i;
22721     HRESULT hr;
22722 
22723     time_start = time(NULL);
22724 
22725     memset(&desc, 0, sizeof(desc));
22726     desc.no_render_target = true;
22727     if (!init_test_context(&context, &desc))
22728         return;
22729     device = context.device;
22730     command_list = context.list;
22731     queue = context.queue;
22732 
22733     hr = ID3D12CommandQueue_GetTimestampFrequency(queue, &timestamp_frequency);
22734     ok(SUCCEEDED(hr), "Failed to get timestamp frequency, hr %#x.\n", hr);
22735 
22736     heap_desc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
22737     heap_desc.Count = ARRAY_SIZE(timestamps);
22738     heap_desc.NodeMask = 0;
22739     hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
22740     ok(SUCCEEDED(hr), "Failed to create query heap, type %u, hr %#x.\n", heap_desc.Type, hr);
22741 
22742     resource = create_readback_buffer(device, sizeof(timestamps));
22743 
22744     for (i = 0; i < ARRAY_SIZE(timestamps); ++i)
22745         ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_TIMESTAMP, i);
22746 
22747     ID3D12GraphicsCommandList_ResolveQueryData(command_list, query_heap,
22748             D3D12_QUERY_TYPE_TIMESTAMP, 0, 1, resource, 0);
22749     ID3D12GraphicsCommandList_ResolveQueryData(command_list, query_heap,
22750             D3D12_QUERY_TYPE_TIMESTAMP, 1, 3, resource, sizeof(uint64_t));
22751 
22752     get_buffer_readback_with_command_list(resource, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
22753 
22754     time_end = time(NULL) + 1;
22755 
22756     for (i = 0; i < ARRAY_SIZE(timestamps); ++i)
22757         timestamps[i] = get_readback_uint64(&rb, i, 0);
22758 
22759     for (i = 0; i < ARRAY_SIZE(timestamps) - 1; ++i)
22760     {
22761         ok(timestamps[i] <= timestamps[i + 1], "Expected timestamps to monotonically increase, "
22762                 "but got %"PRIu64" > %"PRIu64".\n", timestamps[i], timestamps[i + 1]);
22763     }
22764 
22765     time_diff = (uint64_t)difftime(time_end, time_start) * timestamp_frequency;
22766     timestamp_diff = timestamps[ARRAY_SIZE(timestamps) - 1] - timestamps[0];
22767 
22768     ok(timestamp_diff <= time_diff, "Expected timestamp difference to be bounded by CPU time difference, "
22769             "but got %"PRIu64" > %"PRIu64".\n", timestamp_diff, time_diff);
22770 
22771     release_resource_readback(&rb);
22772     ID3D12QueryHeap_Release(query_heap);
22773     ID3D12Resource_Release(resource);
22774     destroy_test_context(&context);
22775 }
22776 
test_query_pipeline_statistics(void)22777 static void test_query_pipeline_statistics(void)
22778 {
22779     D3D12_QUERY_DATA_PIPELINE_STATISTICS *pipeline_statistics;
22780     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
22781     ID3D12GraphicsCommandList *command_list;
22782     struct test_context context;
22783     ID3D12CommandQueue *queue;
22784     ID3D12Device *device;
22785     D3D12_QUERY_HEAP_DESC heap_desc;
22786     ID3D12QueryHeap *query_heap;
22787     ID3D12Resource *resource;
22788     struct resource_readback rb;
22789     unsigned int pixel_count, i;
22790     HRESULT hr;
22791 
22792     if (!init_test_context(&context, NULL))
22793         return;
22794     device = context.device;
22795     command_list = context.list;
22796     queue = context.queue;
22797 
22798     heap_desc.Type = D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS;
22799     heap_desc.Count = 2;
22800     heap_desc.NodeMask = 0;
22801     hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
22802     ok(SUCCEEDED(hr), "Failed to create query heap, type %u, hr %#x.\n", heap_desc.Type, hr);
22803 
22804     resource = create_readback_buffer(device, 2 * sizeof(struct D3D12_QUERY_DATA_PIPELINE_STATISTICS));
22805 
22806     /* First query: do nothing. */
22807     ID3D12GraphicsCommandList_BeginQuery(command_list, query_heap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 0);
22808     ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 0);
22809     ID3D12GraphicsCommandList_ResolveQueryData(command_list, query_heap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 0, 1,
22810             resource, 0);
22811 
22812     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
22813 
22814     /* Second query: draw something simple. */
22815     ID3D12GraphicsCommandList_BeginQuery(command_list, query_heap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 1);
22816 
22817     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
22818     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
22819     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
22820     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
22821     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
22822     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
22823     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
22824 
22825     ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 1);
22826     ID3D12GraphicsCommandList_ResolveQueryData(command_list, query_heap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 1, 1,
22827             resource, sizeof(struct D3D12_QUERY_DATA_PIPELINE_STATISTICS));
22828 
22829     get_buffer_readback_with_command_list(resource, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
22830 
22831     for (i = 0; i < sizeof(struct D3D12_QUERY_DATA_PIPELINE_STATISTICS) / sizeof(uint64_t); ++i)
22832     {
22833         uint64_t value = get_readback_uint64(&rb, i, 0);
22834         ok(!value, "Element %d: Got %"PRIu64", expected 0.\n", i, value);
22835     }
22836 
22837     pipeline_statistics = get_readback_data(&rb, 1, 0, 0, sizeof(*pipeline_statistics));
22838 
22839     /* We read 3 vertices that formed one primitive. */
22840     ok(pipeline_statistics->IAVertices == 3, "IAVertices: Got %"PRIu64", expected 3.\n",
22841             pipeline_statistics->IAVertices);
22842     ok(pipeline_statistics->IAPrimitives == 1, "IAPrimitives: Got %"PRIu64", expected 1.\n",
22843             pipeline_statistics->IAPrimitives);
22844     ok(pipeline_statistics->VSInvocations == 3, "VSInvocations: Got %"PRIu64", expected 3.\n",
22845             pipeline_statistics->VSInvocations);
22846 
22847     /* No geometry shader output primitives.
22848      * Depending on the graphics card, the geometry shader might still have been invoked, so
22849      * GSInvocations might be whatever. */
22850     ok(pipeline_statistics->GSPrimitives == 0, "GSPrimitives: Got %"PRIu64", expected 0.\n",
22851             pipeline_statistics->GSPrimitives);
22852 
22853     /* One primitive sent to the rasterizer, but it might have been broken up into smaller pieces then. */
22854     ok(pipeline_statistics->CInvocations == 1, "CInvocations: Got %"PRIu64", expected 1.\n",
22855             pipeline_statistics->CInvocations);
22856     ok(pipeline_statistics->CPrimitives > 0, "CPrimitives: Got %"PRIu64", expected > 0.\n",
22857             pipeline_statistics->CPrimitives);
22858 
22859     /* Exact number of pixel shader invocations depends on the graphics card. */
22860     pixel_count = context.render_target_desc.Width * context.render_target_desc.Height;
22861     ok(pipeline_statistics->PSInvocations >= pixel_count, "PSInvocations: Got %"PRIu64", expected >= %u.\n",
22862             pipeline_statistics->PSInvocations, pixel_count);
22863 
22864     /* We used no tessellation or compute shaders at all. */
22865     ok(pipeline_statistics->HSInvocations == 0, "HSInvocations: Got %"PRIu64", expected 0.\n",
22866             pipeline_statistics->HSInvocations);
22867     ok(pipeline_statistics->DSInvocations == 0, "DSInvocations: Got %"PRIu64", expected 0.\n",
22868             pipeline_statistics->DSInvocations);
22869     ok(pipeline_statistics->CSInvocations == 0, "CSInvocations: Got %"PRIu64", expected 0.\n",
22870             pipeline_statistics->CSInvocations);
22871 
22872     release_resource_readback(&rb);
22873     ID3D12QueryHeap_Release(query_heap);
22874     ID3D12Resource_Release(resource);
22875     destroy_test_context(&context);
22876 }
22877 
test_query_occlusion(void)22878 static void test_query_occlusion(void)
22879 {
22880     struct test_context_desc desc;
22881     ID3D12GraphicsCommandList *command_list;
22882     struct test_context context;
22883     ID3D12CommandQueue *queue;
22884     ID3D12Device *device;
22885     struct depth_stencil_resource ds;
22886     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
22887     D3D12_QUERY_HEAP_DESC heap_desc;
22888     ID3D12QueryHeap *query_heap;
22889     ID3D12Resource *resource;
22890     struct resource_readback rb;
22891     unsigned int i;
22892     HRESULT hr;
22893 
22894     static const DWORD ps_code[] =
22895     {
22896 #if 0
22897         float depth;
22898 
22899         float main() : SV_Depth
22900         {
22901             return depth;
22902         }
22903 #endif
22904         0x43425844, 0x91af6cd0, 0x7e884502, 0xcede4f54, 0x6f2c9326, 0x00000001, 0x000000b0, 0x00000003,
22905         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
22906         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0xffffffff,
22907         0x00000e01, 0x445f5653, 0x68747065, 0xababab00, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
22908         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x02000065, 0x0000c001, 0x05000036, 0x0000c001,
22909         0x0020800a, 0x00000000, 0x00000000, 0x0100003e,
22910     };
22911     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
22912     static const struct
22913     {
22914         D3D12_QUERY_TYPE type;
22915         bool draw;
22916         float clear_depth;
22917         float depth;
22918     }
22919     tests[] =
22920     {
22921         {D3D12_QUERY_TYPE_OCCLUSION,        false, 1.0f, 0.5f},
22922         {D3D12_QUERY_TYPE_OCCLUSION,        true,  1.0f, 0.5f},
22923         {D3D12_QUERY_TYPE_BINARY_OCCLUSION, false, 1.0f, 0.5f},
22924         {D3D12_QUERY_TYPE_BINARY_OCCLUSION, true,  1.0f, 0.5f},
22925         {D3D12_QUERY_TYPE_OCCLUSION,        false, 0.0f, 0.5f},
22926         {D3D12_QUERY_TYPE_OCCLUSION,        true,  0.0f, 0.5f},
22927         {D3D12_QUERY_TYPE_BINARY_OCCLUSION, false, 0.0f, 0.5f},
22928         {D3D12_QUERY_TYPE_BINARY_OCCLUSION, true,  0.0f, 0.5f},
22929     };
22930 
22931     memset(&desc, 0, sizeof(desc));
22932     desc.no_render_target = true;
22933     if (!init_test_context(&context, &desc))
22934         return;
22935     device = context.device;
22936     command_list = context.list;
22937     queue = context.queue;
22938 
22939     init_depth_stencil(&ds, context.device, 640, 480, 1, 1, DXGI_FORMAT_D32_FLOAT, 0, NULL);
22940     set_viewport(&context.viewport, 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 1.0f);
22941     set_rect(&context.scissor_rect, 0, 0, 640, 480);
22942 
22943     context.root_signature = create_32bit_constants_root_signature(context.device,
22944             0, 1, D3D12_SHADER_VISIBILITY_PIXEL);
22945     init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, &ps, NULL);
22946     pso_desc.NumRenderTargets = 0;
22947     pso_desc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
22948     pso_desc.DepthStencilState.DepthEnable = true;
22949     pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
22950     pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
22951     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
22952             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
22953     ok(SUCCEEDED(hr), "Failed to create graphics pipeline state, hr %#x.\n", hr);
22954 
22955     heap_desc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION;
22956     heap_desc.Count = ARRAY_SIZE(tests);
22957     heap_desc.NodeMask = 0;
22958     hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
22959     ok(SUCCEEDED(hr), "Failed to create query heap, type %u, hr %#x.\n", heap_desc.Type, hr);
22960 
22961     resource = create_readback_buffer(device, ARRAY_SIZE(tests) * sizeof(uint64_t));
22962 
22963     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, NULL, false, &ds.dsv_handle);
22964     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
22965     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
22966     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
22967     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
22968     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
22969 
22970     for (i = 0; i < ARRAY_SIZE(tests); ++i)
22971     {
22972         vkd3d_test_set_context("Test %u", i);
22973 
22974         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
22975                 D3D12_CLEAR_FLAG_DEPTH, tests[i].clear_depth, 0, 0, NULL);
22976 
22977         ID3D12GraphicsCommandList_BeginQuery(command_list, query_heap, tests[i].type, i);
22978 
22979         if (tests[i].draw)
22980         {
22981             ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 1, &tests[i].depth, 0);
22982             ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
22983         }
22984 
22985         ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, tests[i].type, i);
22986         ID3D12GraphicsCommandList_ResolveQueryData(command_list, query_heap, tests[i].type, i, 1,
22987                 resource, i * sizeof(uint64_t));
22988     }
22989     vkd3d_test_set_context(NULL);
22990 
22991     get_buffer_readback_with_command_list(resource, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
22992     for (i = 0; i < ARRAY_SIZE(tests); ++i)
22993     {
22994         const bool samples_passed = tests[i].draw && tests[i].clear_depth > tests[i].depth;
22995         const uint64_t result = get_readback_uint64(&rb, i, 0);
22996         uint64_t expected_result;
22997 
22998         if (tests[i].type == D3D12_QUERY_TYPE_BINARY_OCCLUSION)
22999             expected_result = samples_passed ? 1 : 0;
23000         else
23001             expected_result = samples_passed ? 640 * 480 : 0;
23002 
23003         ok(result == expected_result || (expected_result && result >= expected_result),
23004                 "Test %u: Got unexpected result %"PRIu64".\n", i, result);
23005     }
23006     release_resource_readback(&rb);
23007 
23008     ID3D12QueryHeap_Release(query_heap);
23009     ID3D12Resource_Release(resource);
23010     destroy_depth_stencil(&ds);
23011     destroy_test_context(&context);
23012 }
23013 
test_resolve_non_issued_query_data(void)23014 static void test_resolve_non_issued_query_data(void)
23015 {
23016     static const uint64_t initial_data[] = {0xdeadbeef, 0xdeadbeef, 0xdeadbabe, 0xdeadbeef};
23017     ID3D12Resource *readback_buffer, *upload_buffer;
23018     ID3D12GraphicsCommandList *command_list;
23019     D3D12_QUERY_HEAP_DESC heap_desc;
23020     struct test_context_desc desc;
23021     ID3D12QueryHeap *query_heap;
23022     struct resource_readback rb;
23023     struct test_context context;
23024     ID3D12CommandQueue *queue;
23025     ID3D12Device *device;
23026     uint64_t *timestamps;
23027     HRESULT hr;
23028 
23029     memset(&desc, 0, sizeof(desc));
23030     desc.no_render_target = true;
23031     if (!init_test_context(&context, &desc))
23032         return;
23033     device = context.device;
23034     command_list = context.list;
23035     queue = context.queue;
23036 
23037     heap_desc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
23038     heap_desc.Count = ARRAY_SIZE(initial_data);
23039     heap_desc.NodeMask = 0;
23040     hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
23041     ok(SUCCEEDED(hr), "Failed to create query heap, hr %#x.\n", hr);
23042 
23043     readback_buffer = create_readback_buffer(device, sizeof(initial_data));
23044     upload_buffer = create_upload_buffer(context.device, sizeof(initial_data), initial_data);
23045 
23046     ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_TIMESTAMP, 0);
23047     ID3D12GraphicsCommandList_CopyResource(command_list, readback_buffer, upload_buffer);
23048     ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_TIMESTAMP, 3);
23049     ID3D12GraphicsCommandList_ResolveQueryData(command_list, query_heap,
23050             D3D12_QUERY_TYPE_TIMESTAMP, 0, 4, readback_buffer, 0);
23051 
23052     get_buffer_readback_with_command_list(readback_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
23053     timestamps = get_readback_data(&rb, 0, 0, 0, sizeof(*timestamps));
23054     ok(timestamps[0] != initial_data[0] && timestamps[0] > 0,
23055             "Got unexpected timestamp %#"PRIx64".\n", timestamps[0]);
23056     ok(!timestamps[1], "Got unexpected timestamp %#"PRIx64".\n", timestamps[1]);
23057     ok(!timestamps[2], "Got unexpected timestamp %#"PRIx64".\n", timestamps[2]);
23058     ok(timestamps[3] != initial_data[3] && timestamps[3] > 0,
23059             "Got unexpected timestamp %#"PRIx64".\n", timestamps[3]);
23060     release_resource_readback(&rb);
23061 
23062     ID3D12QueryHeap_Release(query_heap);
23063     ID3D12Resource_Release(readback_buffer);
23064     ID3D12Resource_Release(upload_buffer);
23065     destroy_test_context(&context);
23066 }
23067 
test_resolve_query_data_in_different_command_list(void)23068 static void test_resolve_query_data_in_different_command_list(void)
23069 {
23070     ID3D12GraphicsCommandList *command_list;
23071     D3D12_QUERY_HEAP_DESC heap_desc;
23072     ID3D12Resource *readback_buffer;
23073     struct resource_readback rb;
23074     ID3D12QueryHeap *query_heap;
23075     struct test_context context;
23076     ID3D12CommandQueue *queue;
23077     ID3D12Device *device;
23078     unsigned int i;
23079     HRESULT hr;
23080 
23081     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
23082     const unsigned int readback_buffer_capacity = 4;
23083 
23084     if (!init_test_context(&context, NULL))
23085         return;
23086     device = context.device;
23087     command_list = context.list;
23088     queue = context.queue;
23089 
23090     heap_desc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION;
23091     heap_desc.Count = 1;
23092     heap_desc.NodeMask = 0;
23093     hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
23094     ok(SUCCEEDED(hr), "Failed to create query heap, hr %#x.\n", hr);
23095 
23096     readback_buffer = create_readback_buffer(device, readback_buffer_capacity * sizeof(uint64_t));
23097 
23098     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
23099 
23100     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
23101     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
23102     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
23103     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
23104     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
23105     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
23106 
23107     ID3D12GraphicsCommandList_BeginQuery(command_list, query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0);
23108     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
23109     ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0);
23110 
23111     transition_resource_state(command_list, context.render_target,
23112             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
23113     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
23114 
23115     reset_command_list(command_list, context.allocator);
23116     for (i = 0; i < readback_buffer_capacity / 2; ++i)
23117     {
23118         ID3D12GraphicsCommandList_ResolveQueryData(command_list,
23119                 query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0, 1, readback_buffer, i * sizeof(uint64_t));
23120     }
23121     hr = ID3D12GraphicsCommandList_Close(command_list);
23122     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
23123     exec_command_list(queue, command_list);
23124     wait_queue_idle(context.device, queue);
23125 
23126     reset_command_list(command_list, context.allocator);
23127     for (; i < readback_buffer_capacity; ++i)
23128     {
23129         ID3D12GraphicsCommandList_ResolveQueryData(command_list,
23130                 query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0, 1, readback_buffer, i * sizeof(uint64_t));
23131     }
23132 
23133     get_buffer_readback_with_command_list(readback_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
23134     for (i = 0; i < readback_buffer_capacity; ++i)
23135     {
23136         uint64_t expected_result = context.render_target_desc.Width * context.render_target_desc.Height;
23137         uint64_t result = get_readback_uint64(&rb, i, 0);
23138 
23139         ok(result == expected_result, "Got unexpected result %"PRIu64" at %u.\n", result, i);
23140     }
23141     release_resource_readback(&rb);
23142 
23143     ID3D12QueryHeap_Release(query_heap);
23144     ID3D12Resource_Release(readback_buffer);
23145     destroy_test_context(&context);
23146 }
23147 
test_resolve_query_data_in_reordered_command_list(void)23148 static void test_resolve_query_data_in_reordered_command_list(void)
23149 {
23150     ID3D12GraphicsCommandList *command_lists[2];
23151     ID3D12CommandAllocator *command_allocator;
23152     D3D12_QUERY_HEAP_DESC heap_desc;
23153     ID3D12Resource *readback_buffer;
23154     struct resource_readback rb;
23155     ID3D12QueryHeap *query_heap;
23156     struct test_context context;
23157     ID3D12CommandQueue *queue;
23158     ID3D12Device *device;
23159     uint64_t result;
23160     HRESULT hr;
23161 
23162     if (!init_test_context(&context, NULL))
23163         return;
23164     device = context.device;
23165     command_lists[0] = context.list;
23166     queue = context.queue;
23167 
23168     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
23169             &IID_ID3D12CommandAllocator, (void **)&command_allocator);
23170     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
23171     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
23172             command_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_lists[1]);
23173     ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
23174 
23175     heap_desc.Type = D3D12_QUERY_HEAP_TYPE_OCCLUSION;
23176     heap_desc.Count = 1;
23177     heap_desc.NodeMask = 0;
23178     hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
23179     ok(SUCCEEDED(hr), "Failed to create query heap, hr %#x.\n", hr);
23180 
23181     readback_buffer = create_readback_buffer(device, sizeof(uint64_t));
23182 
23183     /* Read query results in the second command list. */
23184     ID3D12GraphicsCommandList_ResolveQueryData(command_lists[1],
23185             query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0, 1, readback_buffer, 0);
23186     hr = ID3D12GraphicsCommandList_Close(command_lists[1]);
23187     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
23188 
23189     /* Produce query results in the first command list. */
23190     ID3D12GraphicsCommandList_OMSetRenderTargets(command_lists[0], 1, &context.rtv, false, NULL);
23191     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_lists[0], context.root_signature);
23192     ID3D12GraphicsCommandList_SetPipelineState(command_lists[0], context.pipeline_state);
23193     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_lists[0], D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
23194     ID3D12GraphicsCommandList_RSSetViewports(command_lists[0], 1, &context.viewport);
23195     ID3D12GraphicsCommandList_RSSetScissorRects(command_lists[0], 1, &context.scissor_rect);
23196     ID3D12GraphicsCommandList_BeginQuery(command_lists[0], query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0);
23197     ID3D12GraphicsCommandList_DrawInstanced(command_lists[0], 3, 1, 0, 0);
23198     ID3D12GraphicsCommandList_EndQuery(command_lists[0], query_heap, D3D12_QUERY_TYPE_OCCLUSION, 0);
23199     hr = ID3D12GraphicsCommandList_Close(command_lists[0]);
23200     ok(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
23201 
23202     ID3D12CommandQueue_ExecuteCommandLists(queue,
23203             ARRAY_SIZE(command_lists), (ID3D12CommandList **)command_lists);
23204     wait_queue_idle(device, queue);
23205 
23206     reset_command_list(command_lists[0], context.allocator);
23207     get_buffer_readback_with_command_list(readback_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_lists[0]);
23208     result = get_readback_uint64(&rb, 0, 0);
23209     todo ok(result == context.render_target_desc.Width * context.render_target_desc.Height,
23210             "Got unexpected result %"PRIu64".\n", result);
23211     release_resource_readback(&rb);
23212 
23213     ID3D12GraphicsCommandList_Release(command_lists[1]);
23214     ID3D12CommandAllocator_Release(command_allocator);
23215     ID3D12QueryHeap_Release(query_heap);
23216     ID3D12Resource_Release(readback_buffer);
23217     destroy_test_context(&context);
23218 }
23219 
test_execute_indirect(void)23220 static void test_execute_indirect(void)
23221 {
23222     ID3D12Resource *argument_buffer, *count_buffer, *uav;
23223     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
23224     ID3D12CommandSignature *command_signature;
23225     ID3D12GraphicsCommandList *command_list;
23226     D3D12_INPUT_LAYOUT_DESC input_layout;
23227     D3D12_ROOT_PARAMETER root_parameter;
23228     ID3D12PipelineState *pipeline_state;
23229     ID3D12RootSignature *root_signature;
23230     struct test_context_desc desc;
23231     D3D12_VERTEX_BUFFER_VIEW vbv;
23232     D3D12_INDEX_BUFFER_VIEW ibv;
23233     struct resource_readback rb;
23234     struct test_context context;
23235     ID3D12CommandQueue *queue;
23236     ID3D12Resource *vb, *ib;
23237     unsigned int i;
23238     D3D12_BOX box;
23239     HRESULT hr;
23240 
23241     static const struct
23242     {
23243         struct vec4 position;
23244         uint32_t color;
23245     }
23246     vertices[] =
23247     {
23248         {{-1.0f, -1.0f, 0.0f, 1.0f}, 0xffffff00},
23249         {{-1.0f,  1.0f, 0.0f, 1.0f}, 0xffffff00},
23250         {{ 1.0f, -1.0f, 0.0f, 1.0f}, 0xffffff00},
23251         {{ 1.0f,  1.0f, 0.0f, 1.0f}, 0xffffff00},
23252 
23253         {{-1.0f, -1.0f, 0.0f, 1.0f}, 0xff00ff00},
23254         {{-1.0f,  0.5f, 0.0f, 1.0f}, 0xff00ff00},
23255         {{ 0.5f, -1.0f, 0.0f, 1.0f}, 0xff00ff00},
23256         {{ 0.5f,  0.5f, 0.0f, 1.0f}, 0xff00ff00},
23257 
23258         {{-1.0f, -1.0f, 0.0f, 1.0f}, 0xff00ff00},
23259         {{-1.0f,  1.0f, 0.0f, 1.0f}, 0xff00ff00},
23260         {{ 1.0f, -1.0f, 0.0f, 1.0f}, 0xff00ff00},
23261         {{ 1.0f,  1.0f, 0.0f, 1.0f}, 0xff00ff00},
23262     };
23263     static const uint32_t indices[] = {0, 1, 2, 3, 2, 1};
23264     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
23265     {
23266         {"SV_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0,  0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
23267         {"COLOR",       0, DXGI_FORMAT_R8G8B8A8_UNORM,     0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
23268     };
23269     static const DWORD vs_code[] =
23270     {
23271 #if 0
23272         struct vs_data
23273         {
23274             float4 pos : SV_POSITION;
23275             float4 color : COLOR;
23276         };
23277 
23278         void main(in struct vs_data vs_input, out struct vs_data vs_output)
23279         {
23280             vs_output.pos = vs_input.pos;
23281             vs_output.color = vs_input.color;
23282         }
23283 #endif
23284         0x43425844, 0xd5b32785, 0x35332906, 0x4d05e031, 0xf66a58af, 0x00000001, 0x00000144, 0x00000003,
23285         0x0000002c, 0x00000080, 0x000000d4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
23286         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000044, 0x00000000, 0x00000000,
23287         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
23288         0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003,
23289         0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
23290         0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x52444853, 0x00000068, 0x00010040,
23291         0x0000001a, 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x001010f2, 0x00000001, 0x04000067,
23292         0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x001020f2,
23293         0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x001020f2, 0x00000001, 0x00101e46, 0x00000001,
23294         0x0100003e,
23295     };
23296     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
23297     static const DWORD ps_code[] =
23298     {
23299 #if 0
23300         struct ps_data
23301         {
23302             float4 pos : SV_POSITION;
23303             float4 color : COLOR;
23304         };
23305 
23306         float4 main(struct ps_data ps_input) : SV_Target
23307         {
23308             return ps_input.color;
23309         }
23310 #endif
23311         0x43425844, 0x89803e59, 0x3f798934, 0xf99181df, 0xf5556512, 0x00000001, 0x000000f4, 0x00000003,
23312         0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
23313         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000,
23314         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
23315         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
23316         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000038, 0x00000040,
23317         0x0000000e, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x05000036,
23318         0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e,
23319     };
23320     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
23321     static const DWORD cs_code[] =
23322     {
23323 #if 0
23324         RWByteAddressBuffer o;
23325 
23326         [numthreads(1, 1, 1)]
23327         void main(uint3 group_id : SV_groupID)
23328         {
23329             uint idx = group_id.x + group_id.y * 2 + group_id.z * 6;
23330             o.Store(idx * 4, idx);
23331         }
23332 #endif
23333         0x43425844, 0xfdd6a339, 0xf3b8096e, 0xb5977014, 0xcdb26cfd, 0x00000001, 0x00000118, 0x00000003,
23334         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
23335         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000c4, 0x00050050, 0x00000031, 0x0100086a,
23336         0x0300009d, 0x0011e000, 0x00000000, 0x0200005f, 0x00021072, 0x02000068, 0x00000001, 0x0400009b,
23337         0x00000001, 0x00000001, 0x00000001, 0x06000029, 0x00100012, 0x00000000, 0x0002101a, 0x00004001,
23338         0x00000001, 0x0600001e, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0002100a, 0x08000023,
23339         0x00100012, 0x00000000, 0x0002102a, 0x00004001, 0x00000006, 0x0010000a, 0x00000000, 0x07000029,
23340         0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000002, 0x070000a6, 0x0011e012,
23341         0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e,
23342     };
23343     static const struct argument_data
23344     {
23345         D3D12_DRAW_ARGUMENTS draws[4];
23346         D3D12_DISPATCH_ARGUMENTS dispatch;
23347         D3D12_DRAW_INDEXED_ARGUMENTS indexed_draws[2];
23348     }
23349     argument_data =
23350     {
23351         {{6, 1, 4, 0}, {6, 1, 8, 0}, {6, 1, 0, 0}},
23352         {2, 3, 4},
23353         {{6, 1, 0, 0, 0}, {6, 1, 0, 4, 0}},
23354     };
23355     static const uint32_t count_data[] = {2, 1};
23356     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
23357 
23358     memset(&desc, 0, sizeof(desc));
23359     desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
23360     desc.no_pipeline = true;
23361     if (!init_test_context(&context, &desc))
23362         return;
23363     command_list = context.list;
23364     queue = context.queue;
23365 
23366     input_layout.pInputElementDescs = layout_desc;
23367     input_layout.NumElements = ARRAY_SIZE(layout_desc);
23368     context.pipeline_state = create_pipeline_state(context.device,
23369             context.root_signature, context.render_target_desc.Format, &vs, &ps, &input_layout);
23370 
23371     vb = create_upload_buffer(context.device, sizeof(vertices), vertices);
23372     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
23373     vbv.StrideInBytes = sizeof(*vertices);
23374     vbv.SizeInBytes = sizeof(vertices);
23375 
23376     ib = create_upload_buffer(context.device, sizeof(indices), indices);
23377     ibv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(ib);
23378     ibv.SizeInBytes = sizeof(indices);
23379     ibv.Format = DXGI_FORMAT_R32_UINT;
23380 
23381     argument_buffer = create_upload_buffer(context.device, sizeof(argument_data), &argument_data);
23382     count_buffer = create_upload_buffer(context.device, sizeof(count_data), count_data);
23383 
23384     command_signature = create_command_signature(context.device, D3D12_INDIRECT_ARGUMENT_TYPE_DRAW);
23385 
23386     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
23387 
23388     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
23389     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
23390     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
23391     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
23392     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
23393     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
23394     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
23395     ID3D12GraphicsCommandList_ExecuteIndirect(command_list, command_signature, 2, argument_buffer, 0, NULL, 0);
23396 
23397     transition_resource_state(command_list, context.render_target,
23398             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
23399     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
23400 
23401     reset_command_list(command_list, context.allocator);
23402     transition_resource_state(command_list, context.render_target,
23403             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
23404 
23405     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
23406 
23407     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
23408     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
23409     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
23410     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
23411     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
23412     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
23413     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
23414     ID3D12GraphicsCommandList_ExecuteIndirect(command_list, command_signature, 4, argument_buffer, 0,
23415             count_buffer, 0);
23416 
23417     transition_resource_state(command_list, context.render_target,
23418             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
23419     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
23420 
23421     reset_command_list(command_list, context.allocator);
23422 
23423     ID3D12CommandSignature_Release(command_signature);
23424     command_signature = create_command_signature(context.device, D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH);
23425 
23426     uav = create_default_buffer(context.device, 2 * 3 * 4 * sizeof(UINT),
23427             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
23428 
23429     root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
23430     root_parameter.Descriptor.ShaderRegister = 0;
23431     root_parameter.Descriptor.RegisterSpace = 0;
23432     root_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
23433     root_signature_desc.NumParameters = 1;
23434     root_signature_desc.pParameters = &root_parameter;
23435     root_signature_desc.NumStaticSamplers = 0;
23436     root_signature_desc.pStaticSamplers = NULL;
23437     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
23438     hr = create_root_signature(context.device, &root_signature_desc, &root_signature);
23439     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
23440 
23441     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, root_signature);
23442     pipeline_state = create_compute_pipeline_state(context.device, root_signature,
23443             shader_bytecode(cs_code, sizeof(cs_code)));
23444     ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
23445     ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list,
23446             0, ID3D12Resource_GetGPUVirtualAddress(uav));
23447     ID3D12GraphicsCommandList_ExecuteIndirect(command_list, command_signature, 1, argument_buffer,
23448             offsetof(struct argument_data, dispatch), NULL, 0);
23449 
23450     transition_sub_resource_state(command_list, uav, 0,
23451             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
23452     get_buffer_readback_with_command_list(uav, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
23453     for (i = 0; i < rb.width; ++i)
23454     {
23455         unsigned int ret = get_readback_uint(&rb, i, 0, 0);
23456         ok(ret == i, "Got unexpected result %#x at index %u.\n", ret, i);
23457     }
23458     release_resource_readback(&rb);
23459 
23460     reset_command_list(command_list, context.allocator);
23461     transition_resource_state(command_list, context.render_target,
23462             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
23463 
23464     ID3D12CommandSignature_Release(command_signature);
23465     command_signature = create_command_signature(context.device, D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED);
23466 
23467     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
23468 
23469     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
23470     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
23471     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
23472     ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, &ibv);
23473     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
23474     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
23475     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
23476     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
23477     ID3D12GraphicsCommandList_ExecuteIndirect(command_list, command_signature,
23478             ARRAY_SIZE(argument_data.indexed_draws), argument_buffer,
23479             offsetof(struct argument_data, indexed_draws), NULL, 0);
23480 
23481     transition_resource_state(command_list, context.render_target,
23482             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
23483     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
23484     set_box(&box, 0, 0, 0, 32, 8, 1);
23485     check_readback_data_uint(&rb, &box, 0xffffff00, 0);
23486     set_box(&box, 24, 8, 0, 32, 32, 1);
23487     check_readback_data_uint(&rb, &box, 0xffffff00, 0);
23488     set_box(&box, 0, 8, 0, 24, 32, 1);
23489     check_readback_data_uint(&rb, &box, 0xff00ff00, 0);
23490     release_resource_readback(&rb);
23491 
23492     reset_command_list(command_list, context.allocator);
23493     transition_resource_state(command_list, context.render_target,
23494             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
23495 
23496     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
23497 
23498     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
23499     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
23500     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
23501     ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, &ibv);
23502     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
23503     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
23504     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
23505     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
23506     ID3D12GraphicsCommandList_ExecuteIndirect(command_list, command_signature,
23507             ARRAY_SIZE(argument_data.indexed_draws), argument_buffer,
23508             offsetof(struct argument_data, indexed_draws), count_buffer, sizeof(uint32_t));
23509 
23510     transition_resource_state(command_list, context.render_target,
23511             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
23512     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xffffff00, 0);
23513 
23514     ID3D12PipelineState_Release(pipeline_state);
23515     ID3D12RootSignature_Release(root_signature);
23516     ID3D12Resource_Release(ib);
23517     ID3D12Resource_Release(uav);
23518     ID3D12Resource_Release(vb);
23519     ID3D12CommandSignature_Release(command_signature);
23520     ID3D12Resource_Release(argument_buffer);
23521     ID3D12Resource_Release(count_buffer);
23522     destroy_test_context(&context);
23523 }
23524 
test_dispatch_zero_thread_groups(void)23525 static void test_dispatch_zero_thread_groups(void)
23526 {
23527     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
23528     ID3D12CommandSignature *command_signature;
23529     ID3D12GraphicsCommandList *command_list;
23530     D3D12_ROOT_PARAMETER root_parameters[2];
23531     ID3D12Resource *argument_buffer, *uav;
23532     struct resource_readback rb;
23533     struct test_context context;
23534     ID3D12CommandQueue *queue;
23535     unsigned int ret, i;
23536     HRESULT hr;
23537 
23538     static const DWORD cs_code[] =
23539     {
23540 #if 0
23541         RWByteAddressBuffer o;
23542 
23543         uint v;
23544 
23545         [numthreads(1, 1, 1)]
23546         void main()
23547         {
23548             o.Store(0, v);
23549         }
23550 #endif
23551         0x43425844, 0x3ad946e3, 0x83e33b81, 0x83532aa4, 0x40831f89, 0x00000001, 0x000000b0, 0x00000003,
23552         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
23553         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x0000005c, 0x00050050, 0x00000017, 0x0100086a,
23554         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300009d, 0x0011e000, 0x00000000, 0x0400009b,
23555         0x00000001, 0x00000001, 0x00000001, 0x080000a6, 0x0011e012, 0x00000000, 0x00004001, 0x00000000,
23556         0x0020800a, 0x00000000, 0x00000000, 0x0100003e,
23557     };
23558     static const D3D12_DISPATCH_ARGUMENTS argument_data[] =
23559     {
23560         {1, 1, 1},
23561         {0, 3, 4},
23562         {0, 0, 4},
23563         {0, 0, 0},
23564         {4, 0, 0},
23565         {4, 0, 3},
23566         {4, 2, 0},
23567         {0, 2, 0},
23568         {0, 0, 0},
23569     };
23570 
23571     if (!init_compute_test_context(&context))
23572         return;
23573     command_list = context.list;
23574     queue = context.queue;
23575 
23576     argument_buffer = create_upload_buffer(context.device, sizeof(argument_data), &argument_data);
23577 
23578     command_signature = create_command_signature(context.device, D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH);
23579 
23580     uav = create_default_buffer(context.device, 2 * 256, /* minTexelBufferOffsetAlignment */
23581             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
23582 
23583     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
23584     root_parameters[0].Descriptor.ShaderRegister = 0;
23585     root_parameters[0].Descriptor.RegisterSpace = 0;
23586     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
23587     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
23588     root_parameters[1].Constants.ShaderRegister = 0;
23589     root_parameters[1].Constants.RegisterSpace = 0;
23590     root_parameters[1].Constants.Num32BitValues = 1;
23591     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
23592     root_signature_desc.NumParameters = 2;
23593     root_signature_desc.pParameters = root_parameters;
23594     root_signature_desc.NumStaticSamplers = 0;
23595     root_signature_desc.pStaticSamplers = NULL;
23596     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
23597     hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
23598     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
23599 
23600     context.pipeline_state = create_compute_pipeline_state(context.device, context.root_signature,
23601             shader_bytecode(cs_code, sizeof(cs_code)));
23602 
23603     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
23604     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
23605 
23606     ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list,
23607             0, ID3D12Resource_GetGPUVirtualAddress(uav));
23608     for (i = 0; i < ARRAY_SIZE(argument_data); ++i)
23609     {
23610         ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(command_list,
23611                 1, 10 + i, 0);
23612         ID3D12GraphicsCommandList_ExecuteIndirect(command_list, command_signature,
23613                 1, argument_buffer, i * sizeof(*argument_data), NULL, 0);
23614     }
23615 
23616     ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list,
23617             0, ID3D12Resource_GetGPUVirtualAddress(uav) + 256);
23618     for (i = 0; i < ARRAY_SIZE(argument_data); ++i)
23619     {
23620         const D3D12_DISPATCH_ARGUMENTS *arg = &argument_data[i];
23621         ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(command_list,
23622                 1, 50 + i, 0);
23623         ID3D12GraphicsCommandList_Dispatch(command_list,
23624                 arg->ThreadGroupCountX, arg->ThreadGroupCountY, arg->ThreadGroupCountZ);
23625     }
23626 
23627     transition_sub_resource_state(command_list, uav, 0,
23628             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
23629     get_buffer_readback_with_command_list(uav, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
23630     ret = get_readback_uint(&rb, 0, 0, 0);
23631     ok(ret == 10, "Got unexpected result %#x.\n", ret);
23632     ret = get_readback_uint(&rb, 64, 0, 0);
23633     ok(ret == 50, "Got unexpected result %#x.\n", ret);
23634     release_resource_readback(&rb);
23635 
23636     ID3D12Resource_Release(uav);
23637     ID3D12CommandSignature_Release(command_signature);
23638     ID3D12Resource_Release(argument_buffer);
23639     destroy_test_context(&context);
23640 }
23641 
test_zero_vertex_stride(void)23642 static void test_zero_vertex_stride(void)
23643 {
23644     ID3D12PipelineState *instance_pipeline_state;
23645     ID3D12GraphicsCommandList *command_list;
23646     D3D12_INPUT_LAYOUT_DESC input_layout;
23647     D3D12_VERTEX_BUFFER_VIEW vbv[2];
23648     struct test_context_desc desc;
23649     struct test_context context;
23650     ID3D12CommandQueue *queue;
23651     ID3D12Resource *vb[2];
23652 
23653     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
23654     {
23655         {"sv_position", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT,
23656                 D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
23657         {"color",       0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT,
23658                 D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
23659     };
23660     static const D3D12_INPUT_ELEMENT_DESC instance_layout_desc[] =
23661     {
23662         {"sv_position", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT,
23663                 D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
23664         {"color",       0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT,
23665                 D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
23666     };
23667     static const DWORD vs_code[] =
23668     {
23669 #if 0
23670         struct vs_data
23671         {
23672             float4 pos : SV_POSITION;
23673             float4 color : COLOR;
23674         };
23675 
23676         void main(in struct vs_data vs_input, out struct vs_data vs_output)
23677         {
23678             vs_output.pos = vs_input.pos;
23679             vs_output.color = vs_input.color;
23680         }
23681 #endif
23682         0x43425844, 0xd5b32785, 0x35332906, 0x4d05e031, 0xf66a58af, 0x00000001, 0x00000144, 0x00000003,
23683         0x0000002c, 0x00000080, 0x000000d4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
23684         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000044, 0x00000000, 0x00000000,
23685         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
23686         0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003,
23687         0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
23688         0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x52444853, 0x00000068, 0x00010040,
23689         0x0000001a, 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x001010f2, 0x00000001, 0x04000067,
23690         0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x001020f2,
23691         0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x001020f2, 0x00000001, 0x00101e46, 0x00000001,
23692         0x0100003e,
23693     };
23694     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
23695     static const DWORD ps_code[] =
23696     {
23697 #if 0
23698         struct ps_data
23699         {
23700             float4 pos : SV_POSITION;
23701             float4 color : COLOR;
23702         };
23703 
23704         float4 main(struct ps_data ps_input) : SV_Target
23705         {
23706             return ps_input.color;
23707         }
23708 #endif
23709         0x43425844, 0x89803e59, 0x3f798934, 0xf99181df, 0xf5556512, 0x00000001, 0x000000f4, 0x00000003,
23710         0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
23711         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000,
23712         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
23713         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
23714         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000038, 0x00000040,
23715         0x0000000e, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x05000036,
23716         0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e,
23717     };
23718     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
23719     static const struct vec4 positions[] =
23720     {
23721         {-1.0f, -1.0f, 0.0f, 1.0f},
23722         {-1.0f,  1.0f, 0.0f, 1.0f},
23723         { 1.0f, -1.0f, 0.0f, 1.0f},
23724         { 1.0f,  1.0f, 0.0f, 1.0f},
23725     };
23726     static const struct vec4 colors[] =
23727     {
23728         {0.0f, 1.0f, 0.0f, 1.0f},
23729         {1.0f, 0.0f, 0.0f, 1.0f},
23730         {0.5f, 0.5f, 0.5f, 1.0f},
23731         {1.0f, 0.0f, 1.0f, 1.0f},
23732         {1.0f, 0.0f, 1.0f, 1.0f},
23733         {1.0f, 0.0f, 1.0f, 1.0f},
23734         {1.0f, 0.0f, 1.0f, 1.0f},
23735         {1.0f, 0.0f, 1.0f, 1.0f},
23736         {1.0f, 0.0f, 1.0f, 1.0f},
23737     };
23738     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
23739 
23740     memset(&desc, 0, sizeof(desc));
23741     desc.no_root_signature = true;
23742     if (!init_test_context(&context, &desc))
23743         return;
23744     command_list = context.list;
23745     queue = context.queue;
23746 
23747     context.root_signature = create_empty_root_signature(context.device,
23748             D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
23749     input_layout.pInputElementDescs = layout_desc;
23750     input_layout.NumElements = ARRAY_SIZE(layout_desc);
23751     context.pipeline_state = create_pipeline_state(context.device,
23752             context.root_signature, context.render_target_desc.Format, &vs, &ps, &input_layout);
23753 
23754     input_layout.pInputElementDescs = instance_layout_desc;
23755     input_layout.NumElements = ARRAY_SIZE(instance_layout_desc);
23756     instance_pipeline_state = create_pipeline_state(context.device,
23757             context.root_signature, context.render_target_desc.Format, &vs, &ps, &input_layout);
23758 
23759     memset(vbv, 0, sizeof(vbv));
23760     vb[0] = create_upload_buffer(context.device, sizeof(positions), positions);
23761     vbv[0].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb[0]);
23762     vbv[0].StrideInBytes = sizeof(*positions);
23763     vbv[0].SizeInBytes = sizeof(positions);
23764 
23765     vb[1] = create_upload_buffer(context.device, sizeof(colors), colors);
23766     vbv[1].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb[1]) + 2 * sizeof(*colors);
23767     vbv[1].StrideInBytes = 0;
23768     vbv[1].SizeInBytes = sizeof(colors);
23769 
23770     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
23771 
23772     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
23773     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
23774     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
23775     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
23776     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
23777     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
23778     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
23779     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 4, 0, 0);
23780 
23781     transition_resource_state(command_list, context.render_target,
23782             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
23783     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff808080, 2);
23784 
23785     reset_command_list(command_list, context.allocator);
23786     transition_resource_state(command_list, context.render_target,
23787             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
23788 
23789     vbv[1].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb[1]);
23790 
23791     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
23792 
23793     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
23794     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
23795     ID3D12GraphicsCommandList_SetPipelineState(command_list, instance_pipeline_state);
23796     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
23797     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
23798     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
23799     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
23800     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 4, 0, 0);
23801 
23802     transition_resource_state(command_list, context.render_target,
23803             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
23804     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
23805 
23806     ID3D12Resource_Release(vb[1]);
23807     ID3D12Resource_Release(vb[0]);
23808     ID3D12PipelineState_Release(instance_pipeline_state);
23809     destroy_test_context(&context);
23810 }
23811 
test_instance_id(void)23812 static void test_instance_id(void)
23813 {
23814     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
23815     ID3D12CommandSignature *command_signature;
23816     ID3D12GraphicsCommandList *command_list;
23817     D3D12_INPUT_LAYOUT_DESC input_layout;
23818     D3D12_CPU_DESCRIPTOR_HANDLE rtvs[2];
23819     D3D12_VERTEX_BUFFER_VIEW vbv[3];
23820     ID3D12Resource *argument_buffer;
23821     ID3D12Resource *render_target;
23822     struct test_context_desc desc;
23823     struct test_context context;
23824     struct resource_readback rb;
23825     ID3D12CommandQueue *queue;
23826     ID3D12Resource *vb[3];
23827     unsigned int i, j;
23828     HRESULT hr;
23829 
23830     D3D12_INPUT_ELEMENT_DESC layout_desc[] =
23831     {
23832         {"position", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT,
23833                 D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
23834         {"color",    0, DXGI_FORMAT_R8_UNORM,           1, D3D12_APPEND_ALIGNED_ELEMENT,
23835                 D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1},
23836         {"v_offset", 0, DXGI_FORMAT_R32_FLOAT,          2, D3D12_APPEND_ALIGNED_ELEMENT,
23837                 D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1},
23838     };
23839     static const DWORD vs_code[] =
23840     {
23841 #if 0
23842         struct vs_in
23843         {
23844             float4 position : Position;
23845             float color : Color;
23846             float v_offset : V_Offset;
23847             uint instance_id : SV_InstanceId;
23848         };
23849 
23850         struct vs_out
23851         {
23852             float4 position : SV_Position;
23853             float color : Color;
23854             uint instance_id : InstanceId;
23855         };
23856 
23857         void main(vs_in i, out vs_out o)
23858         {
23859             o.position = i.position;
23860             o.position.x += i.v_offset;
23861             o.color = i.color;
23862             o.instance_id = i.instance_id;
23863         }
23864 #endif
23865         0x43425844, 0xcde3cfbf, 0xe2e3d090, 0xe2eb1038, 0x7e5ad1cf, 0x00000001, 0x00000204, 0x00000003,
23866         0x0000002c, 0x000000c4, 0x0000013c, 0x4e475349, 0x00000090, 0x00000004, 0x00000008, 0x00000068,
23867         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000071, 0x00000000, 0x00000000,
23868         0x00000003, 0x00000001, 0x00000101, 0x00000077, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
23869         0x00000101, 0x00000080, 0x00000000, 0x00000008, 0x00000001, 0x00000003, 0x00000101, 0x69736f50,
23870         0x6e6f6974, 0x6c6f4300, 0x5600726f, 0x66664f5f, 0x00746573, 0x495f5653, 0x6174736e, 0x4965636e,
23871         0xabab0064, 0x4e47534f, 0x00000070, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001,
23872         0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
23873         0x00000e01, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000e01, 0x505f5653,
23874         0x7469736f, 0x006e6f69, 0x6f6c6f43, 0x6e490072, 0x6e617473, 0x64496563, 0xababab00, 0x52444853,
23875         0x000000c0, 0x00010040, 0x00000030, 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x00101012,
23876         0x00000001, 0x0300005f, 0x00101012, 0x00000002, 0x04000060, 0x00101012, 0x00000003, 0x00000008,
23877         0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102012, 0x00000001, 0x03000065,
23878         0x00102012, 0x00000002, 0x07000000, 0x00102012, 0x00000000, 0x0010100a, 0x00000000, 0x0010100a,
23879         0x00000002, 0x05000036, 0x001020e2, 0x00000000, 0x00101e56, 0x00000000, 0x05000036, 0x00102012,
23880         0x00000001, 0x0010100a, 0x00000001, 0x05000036, 0x00102012, 0x00000002, 0x0010100a, 0x00000003,
23881         0x0100003e,
23882     };
23883     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
23884     static const DWORD ps_code[] =
23885     {
23886 #if 0
23887         struct vs_out
23888         {
23889             float4 position : SV_Position;
23890             float color : Color;
23891             uint instance_id : InstanceId;
23892         };
23893 
23894         void main(vs_out i, out float4 o0 : SV_Target0, out uint4 o1 : SV_Target1)
23895         {
23896             o0 = float4(i.color, i.color, i.color, 1.0f);
23897             o1 = i.instance_id;
23898         }
23899 #endif
23900         0x43425844, 0xda0ad0bb, 0x4743f5f5, 0xfbc6d0b1, 0x7c8e7df5, 0x00000001, 0x00000170, 0x00000003,
23901         0x0000002c, 0x000000a4, 0x000000f0, 0x4e475349, 0x00000070, 0x00000003, 0x00000008, 0x00000050,
23902         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000,
23903         0x00000003, 0x00000001, 0x00000101, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000002,
23904         0x00000101, 0x505f5653, 0x7469736f, 0x006e6f69, 0x6f6c6f43, 0x6e490072, 0x6e617473, 0x64496563,
23905         0xababab00, 0x4e47534f, 0x00000044, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000000,
23906         0x00000003, 0x00000000, 0x0000000f, 0x00000038, 0x00000001, 0x00000000, 0x00000001, 0x00000001,
23907         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000078, 0x00000040, 0x0000001e,
23908         0x03001062, 0x00101012, 0x00000001, 0x03000862, 0x00101012, 0x00000002, 0x03000065, 0x001020f2,
23909         0x00000000, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x00102072, 0x00000000, 0x00101006,
23910         0x00000001, 0x05000036, 0x00102082, 0x00000000, 0x00004001, 0x3f800000, 0x05000036, 0x001020f2,
23911         0x00000001, 0x00101006, 0x00000002, 0x0100003e,
23912     };
23913     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
23914     static const struct vec4 stream0[] =
23915     {
23916         {-1.00f, 0.0f, 0.0f, 1.0f},
23917         {-1.00f, 1.0f, 0.0f, 1.0f},
23918         {-0.75f, 0.0f, 0.0f, 1.0f},
23919         {-0.75f, 1.0f, 0.0f, 1.0f},
23920         /* indirect draws data */
23921         {-1.00f, -1.0f, 0.0f, 1.0f},
23922         {-1.00f,  0.0f, 0.0f, 1.0f},
23923         {-0.75f, -1.0f, 0.0f, 1.0f},
23924         {-0.75f,  0.0f, 0.0f, 1.0f},
23925     };
23926     static const BYTE stream1[] =
23927     {
23928         0xf0,
23929         0x80,
23930         0x10,
23931         0x40,
23932 
23933         0xaa,
23934         0xbb,
23935         0xcc,
23936         0x90,
23937     };
23938     static const float stream2[] =
23939     {
23940         0.00f,
23941         0.25f,
23942         0.50f,
23943         0.75f,
23944 
23945         1.00f,
23946         1.25f,
23947         1.50f,
23948         1.75f,
23949     };
23950     static const D3D12_DRAW_ARGUMENTS argument_data[] =
23951     {
23952         {4, 4, 4, 0},
23953         {4, 4, 4, 4},
23954     };
23955     static const struct
23956     {
23957         unsigned int color_step_rate;
23958         unsigned int expected_colors[16];
23959     }
23960     tests[] =
23961     {
23962         {0, {0xfff0f0f0, 0xfff0f0f0, 0xfff0f0f0, 0xfff0f0f0, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa,
23963              0xfff0f0f0, 0xfff0f0f0, 0xfff0f0f0, 0xfff0f0f0, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa}},
23964         {1, {0xfff0f0f0, 0xff808080, 0xff101010, 0xff404040, 0xffaaaaaa, 0xffbbbbbb, 0xffcccccc, 0xff909090,
23965              0xfff0f0f0, 0xff808080, 0xff101010, 0xff404040, 0xffaaaaaa, 0xffbbbbbb, 0xffcccccc, 0xff909090}},
23966         {2, {0xfff0f0f0, 0xfff0f0f0, 0xff808080, 0xff808080, 0xffaaaaaa, 0xffaaaaaa, 0xffbbbbbb, 0xffbbbbbb,
23967              0xfff0f0f0, 0xfff0f0f0, 0xff808080, 0xff808080, 0xffaaaaaa, 0xffaaaaaa, 0xffbbbbbb, 0xffbbbbbb}},
23968     };
23969     static const struct
23970     {
23971         D3D12_BOX box;
23972         unsigned int instance_id;
23973     }
23974     expected_results[] =
23975     {
23976         {{ 0, 0, 0, 10, 10, 1}, 0},
23977         {{10, 0, 0, 20, 10, 1}, 1},
23978         {{20, 0, 0, 30, 10, 1}, 2},
23979         {{30, 0, 0, 40, 10, 1}, 3},
23980         {{40, 0, 0, 50, 10, 1}, 0},
23981         {{50, 0, 0, 60, 10, 1}, 1},
23982         {{60, 0, 0, 70, 10, 1}, 2},
23983         {{70, 0, 0, 80, 10, 1}, 3},
23984         /* indirect draws results */
23985         {{ 0, 10, 0, 10, 20, 1}, 0},
23986         {{10, 10, 0, 20, 20, 1}, 1},
23987         {{20, 10, 0, 30, 20, 1}, 2},
23988         {{30, 10, 0, 40, 20, 1}, 3},
23989         {{40, 10, 0, 50, 20, 1}, 0},
23990         {{50, 10, 0, 60, 20, 1}, 1},
23991         {{60, 10, 0, 70, 20, 1}, 2},
23992         {{70, 10, 0, 80, 20, 1}, 3},
23993     };
23994     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
23995 
23996     assert(ARRAY_SIZE(tests->expected_colors) == ARRAY_SIZE(expected_results));
23997 
23998     memset(&desc, 0, sizeof(desc));
23999     desc.rt_width = 80;
24000     desc.rt_height = 20;
24001     desc.rt_descriptor_count = 2;
24002     desc.no_root_signature = true;
24003     if (!init_test_context(&context, &desc))
24004         return;
24005     command_list = context.list;
24006     queue = context.queue;
24007 
24008     context.root_signature = create_empty_root_signature(context.device,
24009             D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
24010 
24011     rtvs[0] = context.rtv;
24012     rtvs[1] = get_cpu_rtv_handle(&context, context.rtv_heap, 1);
24013 
24014     desc.rt_format = DXGI_FORMAT_R32_UINT;
24015     create_render_target(&context, &desc, &render_target, &rtvs[1]);
24016 
24017     vb[0] = create_upload_buffer(context.device, sizeof(stream0), stream0);
24018     vbv[0].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb[0]);
24019     vbv[0].StrideInBytes = sizeof(*stream0);
24020     vbv[0].SizeInBytes = sizeof(stream0);
24021 
24022     vb[1] = create_upload_buffer(context.device, sizeof(stream1), stream1);
24023     vbv[1].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb[1]);
24024     vbv[1].StrideInBytes = sizeof(*stream1);
24025     vbv[1].SizeInBytes = sizeof(stream1);
24026 
24027     vb[2] = create_upload_buffer(context.device, sizeof(stream2), stream2);
24028     vbv[2].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb[2]);
24029     vbv[2].StrideInBytes = sizeof(*stream2);
24030     vbv[2].SizeInBytes = sizeof(stream2);
24031 
24032     command_signature = create_command_signature(context.device, D3D12_INDIRECT_ARGUMENT_TYPE_DRAW);
24033 
24034     argument_buffer = create_upload_buffer(context.device, sizeof(argument_data), &argument_data);
24035 
24036     for (i = 0; i < ARRAY_SIZE(tests); ++i)
24037     {
24038         vkd3d_test_set_context("Test %u", i);
24039 
24040         layout_desc[1].InstanceDataStepRate = tests[i].color_step_rate;
24041         input_layout.pInputElementDescs = layout_desc;
24042         input_layout.NumElements = ARRAY_SIZE(layout_desc);
24043         init_pipeline_state_desc(&pso_desc, context.root_signature, 0, &vs, &ps, &input_layout);
24044         pso_desc.NumRenderTargets = 2;
24045         pso_desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
24046         pso_desc.RTVFormats[1] = DXGI_FORMAT_R32_UINT;
24047         hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
24048                 &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
24049         ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
24050 
24051         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtvs[0], white, 0, NULL);
24052         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtvs[1], white, 0, NULL);
24053 
24054         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 2, rtvs, false, NULL);
24055         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
24056         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
24057         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
24058         ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
24059         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
24060         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
24061         ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 4, 0, 0);
24062         ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 4, 0, 4);
24063 
24064         ID3D12GraphicsCommandList_ExecuteIndirect(command_list, command_signature,
24065                 2, argument_buffer, 0, NULL, 0);
24066 
24067         transition_resource_state(command_list, context.render_target,
24068                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
24069         get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
24070         for (j = 0; j < ARRAY_SIZE(expected_results); ++j)
24071             check_readback_data_uint(&rb, &expected_results[j].box, tests[i].expected_colors[j], 1);
24072         release_resource_readback(&rb);
24073         reset_command_list(command_list, context.allocator);
24074         transition_resource_state(command_list, render_target,
24075                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
24076         get_texture_readback_with_command_list(render_target, 0, &rb, queue, command_list);
24077         for (j = 0; j < ARRAY_SIZE(expected_results); ++j)
24078             check_readback_data_uint(&rb, &expected_results[j].box, expected_results[j].instance_id, 0);
24079         release_resource_readback(&rb);
24080 
24081         reset_command_list(command_list, context.allocator);
24082         transition_resource_state(command_list, context.render_target,
24083                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
24084         transition_resource_state(command_list, render_target,
24085                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
24086 
24087         ID3D12PipelineState_Release(context.pipeline_state);
24088         context.pipeline_state = NULL;
24089     }
24090     vkd3d_test_set_context(NULL);
24091 
24092     ID3D12CommandSignature_Release(command_signature);
24093     ID3D12Resource_Release(argument_buffer);
24094     ID3D12Resource_Release(render_target);
24095     for (i = 0; i < ARRAY_SIZE(vb); ++i)
24096         ID3D12Resource_Release(vb[i]);
24097     destroy_test_context(&context);
24098 }
24099 
test_vertex_id(void)24100 static void test_vertex_id(void)
24101 {
24102     static const DWORD vs_code[] =
24103     {
24104 #if 0
24105         uint4 main(uint id : ID, uint instance_id : SV_InstanceID, uint vertex_id : SV_VertexID) : OUTPUT
24106         {
24107             return uint4(id, instance_id, vertex_id, 0);
24108         }
24109 #endif
24110         0x43425844, 0x5625197b, 0x588ccf8f, 0x48694905, 0x961d19ca, 0x00000001, 0x00000170, 0x00000003,
24111         0x0000002c, 0x000000a4, 0x000000d4, 0x4e475349, 0x00000070, 0x00000003, 0x00000008, 0x00000050,
24112         0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000101, 0x00000053, 0x00000000, 0x00000008,
24113         0x00000001, 0x00000001, 0x00000101, 0x00000061, 0x00000000, 0x00000006, 0x00000001, 0x00000002,
24114         0x00000101, 0x53004449, 0x6e495f56, 0x6e617473, 0x44496563, 0x5f565300, 0x74726556, 0x44497865,
24115         0xababab00, 0x4e47534f, 0x00000028, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
24116         0x00000001, 0x00000000, 0x0000000f, 0x5054554f, 0xab005455, 0x52444853, 0x00000094, 0x00010040,
24117         0x00000025, 0x0300005f, 0x00101012, 0x00000000, 0x04000060, 0x00101012, 0x00000001, 0x00000008,
24118         0x04000060, 0x00101012, 0x00000002, 0x00000006, 0x03000065, 0x001020f2, 0x00000000, 0x05000036,
24119         0x00102012, 0x00000000, 0x0010100a, 0x00000000, 0x05000036, 0x00102022, 0x00000000, 0x0010100a,
24120         0x00000001, 0x05000036, 0x00102042, 0x00000000, 0x0010100a, 0x00000002, 0x05000036, 0x00102082,
24121         0x00000000, 0x00004001, 0x00000000, 0x0100003e,
24122     };
24123     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
24124     D3D12_INPUT_ELEMENT_DESC layout_desc[] =
24125     {
24126         {"ID", 0, DXGI_FORMAT_R32_UINT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
24127     };
24128     static const D3D12_SO_DECLARATION_ENTRY so_declaration[] =
24129     {
24130         {0, "OUTPUT", 0, 0, 4, 0},
24131     };
24132     static const unsigned int strides[] = {16};
24133     static const unsigned int vertices[] =
24134     {
24135         0,
24136         1,
24137         2,
24138 
24139         3,
24140         4,
24141         5,
24142 
24143         6,
24144         7,
24145         8,
24146 
24147         5,
24148         6,
24149         7,
24150 
24151         0xa,
24152         0xb,
24153         0xc,
24154         0xd,
24155 
24156         0xe,
24157         0xf,
24158     };
24159     static const unsigned int indices[] =
24160     {
24161         6, 7, 8,
24162 
24163         0, 1, 2,
24164 
24165         0, 1, 2, 3,
24166 
24167         8, 9,
24168     };
24169     static const D3D12_DRAW_ARGUMENTS argument_data[] =
24170     {
24171         {4, 1, 12, 1},
24172         {2, 3, 16, 0},
24173     };
24174     static const D3D12_DRAW_INDEXED_ARGUMENTS indexed_argument_data[] =
24175     {
24176         {4, 1,  6, 12, 1},
24177         {2, 3, 10,  8, 0},
24178     };
24179     struct uvec4 expected_values[] =
24180     {
24181         {0, 0, 0},
24182         {1, 0, 1},
24183         {2, 0, 2},
24184         {0, 1, 0},
24185         {1, 1, 1},
24186         {2, 1, 2},
24187 
24188         {3, 0, 0},
24189         {4, 0, 1},
24190         {5, 0, 2},
24191 
24192         {6, 0, 6},
24193         {7, 0, 7},
24194         {8, 0, 8},
24195         {6, 1, 6},
24196         {7, 1, 7},
24197         {8, 1, 8},
24198 
24199         {5, 0, 0},
24200         {6, 0, 1},
24201         {7, 0, 2},
24202 
24203         {0xa, 0, 0},
24204         {0xb, 0, 1},
24205         {0xc, 0, 2},
24206         {0xd, 0, 3},
24207 
24208         {0xe, 0, 0},
24209         {0xf, 0, 1},
24210         {0xe, 1, 0},
24211         {0xf, 1, 1},
24212         {0xe, 2, 0},
24213         {0xf, 2, 1},
24214 
24215         {0xa, 0, 0},
24216         {0xb, 0, 1},
24217         {0xc, 0, 2},
24218         {0xd, 0, 3},
24219 
24220         {0xe, 0, 8},
24221         {0xf, 0, 9},
24222         {0xe, 1, 8},
24223         {0xf, 1, 9},
24224         {0xe, 2, 8},
24225         {0xf, 2, 9},
24226     };
24227 
24228     bool found_values[ARRAY_SIZE(expected_values)] = {0};
24229     bool used_values[ARRAY_SIZE(expected_values)] = {0};
24230     ID3D12Resource *args_buffer, *indexed_args_buffer;
24231     ID3D12CommandSignature *indexed_command_signature;
24232     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
24233     ID3D12Resource *counter_buffer, *so_buffer;
24234     ID3D12CommandSignature *command_signature;
24235     ID3D12GraphicsCommandList *command_list;
24236     D3D12_INPUT_LAYOUT_DESC input_layout;
24237     D3D12_STREAM_OUTPUT_BUFFER_VIEW sobv;
24238     ID3D12Resource *upload_buffer;
24239     struct test_context_desc desc;
24240     D3D12_VERTEX_BUFFER_VIEW vbv;
24241     D3D12_INDEX_BUFFER_VIEW ibv;
24242     struct resource_readback rb;
24243     struct test_context context;
24244     ID3D12CommandQueue *queue;
24245     ID3D12Resource *vb, *ib;
24246     ID3D12Device *device;
24247     unsigned int count;
24248     unsigned int i, j;
24249     HRESULT hr;
24250 
24251     memset(&desc, 0, sizeof(desc));
24252     desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT
24253             | D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT;
24254     desc.no_pipeline = true;
24255     if (!init_test_context(&context, &desc))
24256         return;
24257     device = context.device;
24258     command_list = context.list;
24259     queue = context.queue;
24260 
24261     input_layout.pInputElementDescs = layout_desc;
24262     input_layout.NumElements = ARRAY_SIZE(layout_desc);
24263 
24264     init_pipeline_state_desc(&pso_desc, context.root_signature, 0, &vs, NULL, &input_layout);
24265     memset(&pso_desc.PS, 0, sizeof(pso_desc.PS));
24266     pso_desc.StreamOutput.NumEntries = ARRAY_SIZE(so_declaration);
24267     pso_desc.StreamOutput.pSODeclaration = so_declaration;
24268     pso_desc.StreamOutput.pBufferStrides = strides;
24269     pso_desc.StreamOutput.NumStrides = ARRAY_SIZE(strides);
24270     pso_desc.StreamOutput.RasterizedStream = D3D12_SO_NO_RASTERIZED_STREAM;
24271     pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
24272     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
24273             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
24274     if (hr == E_NOTIMPL)
24275     {
24276         skip("Stream output is not supported.\n");
24277         destroy_test_context(&context);
24278         return;
24279     }
24280     ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
24281 
24282     vb = create_upload_buffer(context.device, sizeof(vertices), vertices);
24283     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
24284     vbv.StrideInBytes = sizeof(*vertices);
24285     vbv.SizeInBytes = sizeof(vertices);
24286 
24287     ib = create_upload_buffer(context.device, sizeof(indices), indices);
24288     ibv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(ib);
24289     ibv.SizeInBytes = sizeof(indices);
24290     ibv.Format = DXGI_FORMAT_R32_UINT;
24291 
24292     args_buffer = create_upload_buffer(device, sizeof(argument_data), &argument_data);
24293     indexed_args_buffer = create_upload_buffer(device, sizeof(indexed_argument_data), &indexed_argument_data);
24294 
24295     command_signature = create_command_signature(device, D3D12_INDIRECT_ARGUMENT_TYPE_DRAW);
24296     indexed_command_signature = create_command_signature(device, D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED);
24297 
24298     count = 0;
24299     upload_buffer = create_upload_buffer(device, sizeof(count), &count);
24300 
24301     counter_buffer = create_default_buffer(device, 32,
24302             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
24303     so_buffer = create_default_buffer(device, 1024,
24304             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_STREAM_OUT);
24305     sobv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(so_buffer);
24306     sobv.SizeInBytes = 1024;
24307     sobv.BufferFilledSizeLocation = ID3D12Resource_GetGPUVirtualAddress(counter_buffer);
24308 
24309     ID3D12GraphicsCommandList_CopyBufferRegion(command_list, counter_buffer, 0,
24310             upload_buffer, 0, sizeof(count));
24311 
24312     transition_resource_state(command_list, counter_buffer,
24313             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_STREAM_OUT);
24314 
24315     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
24316     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
24317     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
24318     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
24319     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_POINTLIST);
24320     ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, &ibv);
24321     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
24322 
24323     ID3D12GraphicsCommandList_SOSetTargets(command_list, 0, 1, &sobv);
24324 
24325     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 2, 0, 0);
24326     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 3, 16);
24327 
24328     ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, 3, 2, 0, 0, 0);
24329     ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, 3, 1, 3, 9, 7);
24330 
24331     ID3D12GraphicsCommandList_ExecuteIndirect(command_list,
24332             command_signature, 1, args_buffer, 0, NULL, 0);
24333     ID3D12GraphicsCommandList_ExecuteIndirect(command_list,
24334             command_signature, 1, args_buffer, sizeof(*argument_data), NULL, 0);
24335 
24336     ID3D12GraphicsCommandList_ExecuteIndirect(command_list,
24337             indexed_command_signature, 1, indexed_args_buffer, 0, NULL, 0);
24338     ID3D12GraphicsCommandList_ExecuteIndirect(command_list,
24339             indexed_command_signature, 1, indexed_args_buffer, sizeof(*indexed_argument_data), NULL, 0);
24340 
24341     transition_resource_state(command_list, counter_buffer,
24342             D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
24343     transition_resource_state(command_list, so_buffer,
24344             D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
24345 
24346     get_buffer_readback_with_command_list(counter_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
24347     count = get_readback_uint(&rb, 0, 0, 0);
24348     ok(count == ARRAY_SIZE(expected_values) * sizeof(struct vec4), "Got counter value %u, expected %uu.\n",
24349             count, (unsigned int)(ARRAY_SIZE(expected_values) * sizeof(struct vec4)));
24350     release_resource_readback(&rb);
24351     reset_command_list(command_list, context.allocator);
24352     count /= sizeof(struct vec4);
24353 
24354     count = min(count, ARRAY_SIZE(used_values));
24355     get_buffer_readback_with_command_list(so_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
24356     for (i = 0; i < ARRAY_SIZE(expected_values); ++i)
24357     {
24358         for (j = 0; j < count; ++j)
24359         {
24360             if (!used_values[j] && compare_uvec4(get_readback_uvec4(&rb, j, 0), &expected_values[i]))
24361             {
24362                 found_values[i] = true;
24363                 used_values[j] = true;
24364                 break;
24365             }
24366         }
24367     }
24368 
24369     for (i = 0; i < count; ++i)
24370     {
24371         const struct uvec4 *v = get_readback_uvec4(&rb, i, 0);
24372         ok(used_values[i], "Found unexpected value {0x%08x, 0x%08x, 0x%08x, 0x%08x}.\n", v->x, v->y, v->z, v->w);
24373     }
24374     release_resource_readback(&rb);
24375 
24376     for (i = 0; i < ARRAY_SIZE(expected_values); ++i)
24377     {
24378         ok(found_values[i], "Failed to find value {0x%08x, 0x%08x, 0x%08x, 0x%08x}.\n",
24379                 expected_values[i].x, expected_values[i].y, expected_values[i].z, expected_values[i].w);
24380     }
24381 
24382     ID3D12CommandSignature_Release(command_signature);
24383     ID3D12CommandSignature_Release(indexed_command_signature);
24384     ID3D12Resource_Release(args_buffer);
24385     ID3D12Resource_Release(counter_buffer);
24386     ID3D12Resource_Release(ib);
24387     ID3D12Resource_Release(indexed_args_buffer);
24388     ID3D12Resource_Release(so_buffer);
24389     ID3D12Resource_Release(upload_buffer);
24390     ID3D12Resource_Release(vb);
24391     destroy_test_context(&context);
24392 }
24393 
test_copy_texture(void)24394 static void test_copy_texture(void)
24395 {
24396     D3D12_TEXTURE_COPY_LOCATION src_location, dst_location;
24397     ID3D12Resource *src_texture, *dst_texture;
24398     ID3D12GraphicsCommandList *command_list;
24399     D3D12_SUBRESOURCE_DATA texture_data;
24400     struct depth_stencil_resource ds;
24401     struct test_context_desc desc;
24402     struct test_context context;
24403     struct resource_readback rb;
24404     ID3D12DescriptorHeap *heap;
24405     ID3D12CommandQueue *queue;
24406     ID3D12Device *device;
24407     unsigned int x, y, i;
24408     D3D12_BOX box;
24409 
24410     static const unsigned int clear_data[] =
24411     {
24412         0x00000000, 0x00000000, 0x00000000, 0x00000000,
24413         0x00000000, 0x00000000, 0x00000000, 0x00000000,
24414         0x00000000, 0x00000000, 0x00000000, 0x00000000,
24415         0x00000000, 0x00000000, 0x00000000, 0x00000000,
24416     };
24417     static const unsigned int bitmap_data[] =
24418     {
24419         0xff00ff00, 0xff00ff01, 0xff00ff02, 0xff00ff03,
24420         0xff00ff10, 0xff00ff12, 0xff00ff12, 0xff00ff13,
24421         0xff00ff20, 0xff00ff21, 0xff00ff22, 0xff00ff23,
24422         0xff00ff30, 0xff00ff31, 0xff00ff32, 0xff00ff33,
24423     };
24424     static const unsigned int result_data[] =
24425     {
24426         0x00000000, 0x00000000, 0x00000000, 0x00000000,
24427         0x00000000, 0xff00ff00, 0xff00ff01, 0x00000000,
24428         0x00000000, 0xff00ff10, 0xff00ff12, 0x00000000,
24429         0x00000000, 0x00000000, 0x00000000, 0x00000000,
24430     };
24431     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
24432     static const DWORD ps_code[] =
24433     {
24434 #if 0
24435         Texture2D<float> t;
24436 
24437         float main(float4 position : SV_Position) : SV_Target
24438         {
24439             return t[int2(position.x, position.y)];
24440         }
24441 #endif
24442         0x43425844, 0x0beace24, 0x5e10b05b, 0x742de364, 0xb2b65d2b, 0x00000001, 0x00000140, 0x00000003,
24443         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
24444         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
24445         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
24446         0x00000000, 0x00000e01, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000a4, 0x00000040,
24447         0x00000029, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000,
24448         0x00000001, 0x03000065, 0x00102012, 0x00000000, 0x02000068, 0x00000001, 0x0500001b, 0x00100032,
24449         0x00000000, 0x00101046, 0x00000000, 0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000,
24450         0x00000000, 0x00000000, 0x00000000, 0x0700002d, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
24451         0x00107e46, 0x00000000, 0x05000036, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e,
24452     };
24453     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
24454     static const float depth_values[] = {0.0f, 0.5f, 0.7f, 1.0f};
24455     static const D3D12_RESOURCE_STATES resource_states[] =
24456     {
24457         D3D12_RESOURCE_STATE_COPY_SOURCE,
24458         D3D12_RESOURCE_STATE_GENERIC_READ,
24459     };
24460 
24461     memset(&desc, 0, sizeof(desc));
24462     desc.rt_format = DXGI_FORMAT_R32_FLOAT;
24463     desc.no_root_signature = true;
24464     if (!init_test_context(&context, &desc))
24465         return;
24466     device = context.device;
24467     command_list = context.list;
24468     queue = context.queue;
24469 
24470     for (i = 0; i < ARRAY_SIZE(resource_states); ++i)
24471     {
24472         src_texture = create_default_texture(device, 4, 4, DXGI_FORMAT_R8G8B8A8_UNORM,
24473                 0, D3D12_RESOURCE_STATE_COPY_DEST);
24474         texture_data.pData = bitmap_data;
24475         texture_data.RowPitch = 4 * sizeof(*bitmap_data);
24476         texture_data.SlicePitch = texture_data.RowPitch * 4;
24477         upload_texture_data(src_texture, &texture_data, 1, queue, command_list);
24478         reset_command_list(command_list, context.allocator);
24479 
24480         dst_texture = create_default_texture(device, 4, 4, DXGI_FORMAT_R8G8B8A8_UNORM,
24481                 0, D3D12_RESOURCE_STATE_COPY_DEST);
24482         texture_data.pData = clear_data;
24483         texture_data.RowPitch = 4 * sizeof(*bitmap_data);
24484         texture_data.SlicePitch = texture_data.RowPitch * 4;
24485         upload_texture_data(dst_texture, &texture_data, 1, queue, command_list);
24486         reset_command_list(command_list, context.allocator);
24487         transition_resource_state(command_list, src_texture,
24488                 D3D12_RESOURCE_STATE_COPY_DEST, resource_states[i]);
24489 
24490         src_location.pResource = src_texture;
24491         src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
24492         src_location.SubresourceIndex = 0;
24493         dst_location.pResource = dst_texture;
24494         dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
24495         dst_location.SubresourceIndex = 0;
24496         set_box(&box, 0, 0, 0, 2, 2, 1);
24497         ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24498                 &dst_location, 1, 1, 0, &src_location, &box);
24499 
24500         transition_resource_state(command_list, dst_texture,
24501                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
24502         get_texture_readback_with_command_list(dst_texture, 0, &rb, queue, command_list);
24503         for (y = 0; y < 4; ++y)
24504         {
24505             for (x = 0; x < 4; ++x)
24506             {
24507                 unsigned int color = get_readback_uint(&rb, x, y, 0);
24508                 unsigned int expected = result_data[y * 4 + x];
24509 
24510                 ok(color == expected,
24511                         "Got unexpected color 0x%08x at (%u, %u), expected 0x%08x.\n",
24512                         color, x, y, expected);
24513             }
24514         }
24515         release_resource_readback(&rb);
24516         ID3D12Resource_Release(src_texture);
24517         ID3D12Resource_Release(dst_texture);
24518         reset_command_list(command_list, context.allocator);
24519     }
24520 
24521     context.root_signature = create_texture_root_signature(device,
24522             D3D12_SHADER_VISIBILITY_PIXEL, 0, 0);
24523     context.pipeline_state = create_pipeline_state(device,
24524             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
24525 
24526     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
24527 
24528     for (i = 0; i < ARRAY_SIZE(depth_values); ++i)
24529     {
24530         init_depth_stencil(&ds, device, context.render_target_desc.Width,
24531                 context.render_target_desc.Height, 1, 1, DXGI_FORMAT_D32_FLOAT,
24532                 DXGI_FORMAT_D32_FLOAT, NULL);
24533         ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
24534                 D3D12_CLEAR_FLAG_DEPTH, depth_values[i], 0, 0, NULL);
24535         transition_sub_resource_state(command_list, ds.texture, 0,
24536                 D3D12_RESOURCE_STATE_DEPTH_WRITE, resource_states[i % ARRAY_SIZE(resource_states)]);
24537 
24538         dst_texture = create_default_texture(device, 32, 32, DXGI_FORMAT_R32_FLOAT,
24539                 0, D3D12_RESOURCE_STATE_COPY_DEST);
24540         ID3D12Device_CreateShaderResourceView(device, dst_texture, NULL,
24541                 ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap));
24542 
24543         src_location.pResource = ds.texture;
24544         src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
24545         src_location.SubresourceIndex = 0;
24546         dst_location.pResource = dst_texture;
24547         dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
24548         dst_location.SubresourceIndex = 0;
24549         ID3D12GraphicsCommandList_CopyTextureRegion(command_list, &dst_location, 0, 0, 0,
24550                 &src_location, NULL);
24551         transition_sub_resource_state(command_list, dst_texture, 0,
24552                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
24553 
24554         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
24555         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
24556         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
24557         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
24558 
24559         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
24560 
24561         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
24562         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
24563         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
24564                 ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap));
24565         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
24566         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
24567 
24568         transition_sub_resource_state(command_list, context.render_target, 0,
24569                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
24570         check_sub_resource_float(context.render_target, 0, queue, command_list, depth_values[i], 2);
24571 
24572         destroy_depth_stencil(&ds);
24573         ID3D12Resource_Release(dst_texture);
24574 
24575         reset_command_list(command_list, context.allocator);
24576         transition_sub_resource_state(command_list, context.render_target, 0,
24577                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
24578     }
24579 
24580     ID3D12DescriptorHeap_Release(heap);
24581     destroy_test_context(&context);
24582 }
24583 
test_copy_texture_buffer(void)24584 static void test_copy_texture_buffer(void)
24585 {
24586     D3D12_TEXTURE_COPY_LOCATION src_location, dst_location;
24587     ID3D12GraphicsCommandList *command_list;
24588     D3D12_SUBRESOURCE_DATA texture_data;
24589     ID3D12Resource *dst_buffers[4];
24590     struct test_context_desc desc;
24591     struct test_context context;
24592     struct resource_readback rb;
24593     ID3D12Resource *src_texture;
24594     unsigned int got, expected;
24595     ID3D12CommandQueue *queue;
24596     ID3D12Device *device;
24597     unsigned int x, y;
24598     unsigned int *ptr;
24599     unsigned int i;
24600     D3D12_BOX box;
24601 
24602     memset(&desc, 0, sizeof(desc));
24603     desc.no_render_target = true;
24604     if (!init_test_context(&context, &desc))
24605         return;
24606     device = context.device;
24607     command_list = context.list;
24608     queue = context.queue;
24609 
24610     ptr = calloc(64 * 32, sizeof(*ptr));
24611     ok(ptr, "Failed to allocate memory.\n");
24612 
24613     for (i = 0; i < 64 * 32; ++i)
24614         ptr[i] = i;
24615 
24616     src_texture = create_default_texture(device,
24617             64, 32, DXGI_FORMAT_R32_UINT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
24618     texture_data.pData = ptr;
24619     texture_data.RowPitch = 64 * sizeof(*ptr);
24620     texture_data.SlicePitch = texture_data.RowPitch * 32;
24621     upload_texture_data(src_texture, &texture_data, 1, queue, command_list);
24622     reset_command_list(command_list, context.allocator);
24623     transition_resource_state(command_list, src_texture,
24624             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
24625 
24626     free(ptr);
24627 
24628     for (i = 0; i < ARRAY_SIZE(dst_buffers); ++i)
24629     {
24630         dst_buffers[i] = create_default_buffer(device,
24631                 64 * 32 * sizeof(*ptr), 0, D3D12_RESOURCE_STATE_COPY_DEST);
24632     }
24633 
24634     dst_location.pResource = dst_buffers[0];
24635     dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
24636     dst_location.PlacedFootprint.Offset = 0;
24637     dst_location.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R32_UINT;
24638     dst_location.PlacedFootprint.Footprint.Width = 64;
24639     dst_location.PlacedFootprint.Footprint.Height = 32;
24640     dst_location.PlacedFootprint.Footprint.Depth = 1;
24641     dst_location.PlacedFootprint.Footprint.RowPitch = 64 * sizeof(*ptr);
24642 
24643     src_location.pResource = src_texture;
24644     src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
24645     src_location.SubresourceIndex = 0;
24646 
24647     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24648             &dst_location, 0, 0, 0, &src_location, NULL);
24649 
24650     dst_location.pResource = dst_buffers[1];
24651     for (y = 0; y < 32; ++y)
24652     {
24653         set_box(&box, 0, y, 0, 64, y + 1, 1);
24654         ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24655                 &dst_location, 0, 31 - y, 0, &src_location, &box);
24656     }
24657 
24658     dst_location.pResource = dst_buffers[2];
24659     for (x = 0; x < 64; ++x)
24660     {
24661         set_box(&box, x, 0, 0, x + 1, 32, 1);
24662         ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24663                 &dst_location, 63 - x, 0, 0, &src_location, &box);
24664     }
24665 
24666     dst_location.pResource = dst_buffers[3];
24667     set_box(&box, 0, 0, 0, 32, 32, 1);
24668     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24669             &dst_location, 0, 0, 0, &src_location, &box);
24670     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24671             &dst_location, 32, 0, 0, &src_location, &box);
24672 
24673     /* empty box */
24674     set_box(&box, 128, 0, 0, 32, 32, 1);
24675     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24676             &dst_location, 0, 0, 0, &src_location, &box);
24677 
24678     for (i = 0; i < ARRAY_SIZE(dst_buffers); ++i)
24679     {
24680         transition_resource_state(command_list, dst_buffers[i],
24681                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
24682     }
24683 
24684     got = expected = 0;
24685     get_buffer_readback_with_command_list(dst_buffers[0], DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
24686     for (i = 0; i < 64 * 32; ++i)
24687     {
24688         got = get_readback_uint(&rb, i, 0, 0);
24689         expected = i;
24690 
24691         if (got != expected)
24692             break;
24693     }
24694     release_resource_readback(&rb);
24695     ok(got == expected, "Got unexpected value 0x%08x at %u, expected 0x%08x.\n", got, i, expected);
24696 
24697     reset_command_list(command_list, context.allocator);
24698     got = expected = 0;
24699     get_buffer_readback_with_command_list(dst_buffers[1], DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
24700     for (y = 0; y < 32; ++y)
24701     {
24702         for (x = 0; x < 64; ++x)
24703         {
24704             got = get_readback_uint(&rb, 64 * y + x, 0, 0);
24705             expected = 64 * (31 - y) + x;
24706 
24707             if (got != expected)
24708                 break;
24709         }
24710         if (got != expected)
24711             break;
24712     }
24713     release_resource_readback(&rb);
24714     ok(got == expected, "Got unexpected value 0x%08x at (%u, %u), expected 0x%08x.\n", got, x, y, expected);
24715 
24716     reset_command_list(command_list, context.allocator);
24717     got = expected = 0;
24718     get_buffer_readback_with_command_list(dst_buffers[2], DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
24719     for (y = 0; y < 32; ++y)
24720     {
24721         for (x = 0; x < 64; ++x)
24722         {
24723             got = get_readback_uint(&rb, 64 * y + x, 0, 0);
24724             expected = 64 * y + 63 - x;
24725 
24726             if (got != expected)
24727                 break;
24728         }
24729         if (got != expected)
24730             break;
24731     }
24732     release_resource_readback(&rb);
24733     ok(got == expected, "Got unexpected value 0x%08x at (%u, %u), expected 0x%08x.\n", got, x, y, expected);
24734 
24735     reset_command_list(command_list, context.allocator);
24736     got = expected = 0;
24737     get_buffer_readback_with_command_list(dst_buffers[3], DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
24738     for (y = 0; y < 32; ++y)
24739     {
24740         for (x = 0; x < 64; ++x)
24741         {
24742             got = get_readback_uint(&rb, 64 * y + x, 0, 0);
24743             expected = 64 * y + x % 32;
24744 
24745             if (got != expected)
24746                 break;
24747         }
24748         if (got != expected)
24749             break;
24750     }
24751     release_resource_readback(&rb);
24752     ok(got == expected, "Got unexpected value 0x%08x at (%u, %u), expected 0x%08x.\n", got, x, y, expected);
24753 
24754     ID3D12Resource_Release(src_texture);
24755     for (i = 0; i < ARRAY_SIZE(dst_buffers); ++i)
24756         ID3D12Resource_Release(dst_buffers[i]);
24757     destroy_test_context(&context);
24758 }
24759 
test_copy_buffer_texture(void)24760 static void test_copy_buffer_texture(void)
24761 {
24762     D3D12_TEXTURE_COPY_LOCATION src_location, dst_location;
24763     ID3D12GraphicsCommandList *command_list;
24764     struct test_context_desc desc;
24765     struct test_context context;
24766     struct resource_readback rb;
24767     ID3D12Resource *zero_buffer;
24768     ID3D12Resource *dst_texture;
24769     ID3D12Resource *src_buffer;
24770     unsigned int got, expected;
24771     ID3D12CommandQueue *queue;
24772     unsigned int buffer_size;
24773     ID3D12Device *device;
24774     unsigned int x, y, z;
24775     unsigned int *ptr;
24776     unsigned int i;
24777     D3D12_BOX box;
24778     HRESULT hr;
24779 
24780     memset(&desc, 0, sizeof(desc));
24781     desc.no_render_target = true;
24782     if (!init_test_context(&context, &desc))
24783         return;
24784     device = context.device;
24785     command_list = context.list;
24786     queue = context.queue;
24787 
24788     buffer_size = 128 * 100 * 64;
24789 
24790     zero_buffer = create_upload_buffer(device, buffer_size * sizeof(*ptr) + D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT, NULL);
24791     hr = ID3D12Resource_Map(zero_buffer, 0, NULL, (void **)&ptr);
24792     ok(hr == S_OK, "Failed to map buffer, hr %#x.\n", hr);
24793     memset(ptr, 0, buffer_size * sizeof(*ptr) + D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
24794     for (i = 0; i < D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT / sizeof(*ptr); ++i)
24795         ptr[i] = 0xdeadbeef;
24796     ID3D12Resource_Unmap(zero_buffer, 0, NULL);
24797 
24798     src_buffer = create_upload_buffer(device, buffer_size * sizeof(*ptr), NULL);
24799     hr = ID3D12Resource_Map(src_buffer, 0, NULL, (void **)&ptr);
24800     ok(hr == S_OK, "Failed to map buffer, hr %#x.\n", hr);
24801     for (z = 0; z < 64; ++z)
24802     {
24803         for (y = 0; y < 100; ++y)
24804         {
24805             for (x = 0; x < 128; ++x)
24806             {
24807                 ptr[z * 128 * 100 + y * 128 + x] = (z + 1) << 16 | (y + 1) << 8 | (x + 1);
24808             }
24809         }
24810     }
24811     ID3D12Resource_Unmap(src_buffer, 0, NULL);
24812 
24813     dst_texture = create_default_texture3d(device, 128, 100, 64, 2,
24814             DXGI_FORMAT_R32_UINT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
24815 
24816     dst_location.pResource = dst_texture;
24817     dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
24818     dst_location.SubresourceIndex = 0;
24819 
24820     src_location.pResource = zero_buffer;
24821     src_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
24822     src_location.PlacedFootprint.Offset = D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT;
24823     src_location.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R32_UINT;
24824     src_location.PlacedFootprint.Footprint.Width = 128;
24825     src_location.PlacedFootprint.Footprint.Height = 100;
24826     src_location.PlacedFootprint.Footprint.Depth = 64;
24827     src_location.PlacedFootprint.Footprint.RowPitch = 128 * sizeof(*ptr);
24828 
24829     /* fill with 0 */
24830     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24831             &dst_location, 0, 0, 0, &src_location, NULL);
24832 
24833     src_location.pResource = src_buffer;
24834     src_location.PlacedFootprint.Offset = 0;
24835 
24836     /* copy region 1 */
24837     set_box(&box, 64, 16, 8, 128, 100, 64);
24838     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24839             &dst_location, 64, 16, 8, &src_location, &box);
24840 
24841     /* empty boxes */
24842     for (z = 0; z < 2; ++z)
24843     {
24844         for (y = 0; y < 4; ++y)
24845         {
24846             for (x = 0; x < 8; ++x)
24847             {
24848                 set_box(&box, x, y, z, x, y, z);
24849                 ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24850                         &dst_location, 0, 0, 0, &src_location, &box);
24851                 ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24852                         &dst_location, x, y, z, &src_location, &box);
24853             }
24854         }
24855     }
24856 
24857     /* copy region 2 */
24858     set_box(&box, 0, 0, 0, 4, 4, 4);
24859     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24860             &dst_location, 2, 2, 2, &src_location, &box);
24861 
24862     /* fill sub-resource 1 */
24863     dst_location.SubresourceIndex = 1;
24864     set_box(&box, 0, 0, 0, 64, 50, 32);
24865     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24866             &dst_location, 0, 0, 0, &src_location, &box);
24867 
24868     transition_resource_state(command_list, dst_texture,
24869             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
24870 
24871     got = expected = 0;
24872     get_texture_readback_with_command_list(dst_texture, 0, &rb, queue, command_list);
24873     for (z = 0; z < 64; ++z)
24874     {
24875         for (y = 0; y < 100; ++y)
24876         {
24877             for (x = 0; x < 128; ++x)
24878             {
24879                 got = get_readback_uint(&rb, x, y, z);
24880 
24881                 if (2 <= x && x < 6 && 2 <= y && y < 6 && 2 <= z && z < 6)
24882                     expected = (z - 1) << 16 | (y - 1) << 8 | (x - 1); /* copy region 1 */
24883                 else if (64 <= x && 16 <= y && 8 <= z)
24884                     expected = (z + 1) << 16 | (y + 1) << 8 | (x + 1); /* copy region 2 */
24885                 else
24886                     expected = 0;
24887 
24888                 if (got != expected)
24889                     break;
24890             }
24891             if (got != expected)
24892                 break;
24893         }
24894         if (got != expected)
24895             break;
24896     }
24897     release_resource_readback(&rb);
24898     ok(got == expected,
24899             "Got unexpected value 0x%08x at (%u, %u, %u), expected 0x%08x.\n",
24900             got, x, y, z, expected);
24901 
24902     reset_command_list(command_list, context.allocator);
24903     got = expected = 0;
24904     get_texture_readback_with_command_list(dst_texture, 1, &rb, queue, command_list);
24905     for (z = 0; z < 32; ++z)
24906     {
24907         for (y = 0; y < 50; ++y)
24908         {
24909             for (x = 0; x < 64; ++x)
24910             {
24911                 got = get_readback_uint(&rb, x, y, z);
24912                 expected = (z + 1) << 16 | (y + 1) << 8 | (x + 1);
24913 
24914                 if (got != expected)
24915                     break;
24916             }
24917             if (got != expected)
24918                 break;
24919         }
24920         if (got != expected)
24921             break;
24922     }
24923     release_resource_readback(&rb);
24924     ok(got == expected,
24925             "Got unexpected value 0x%08x at (%u, %u, %u), expected 0x%08x.\n",
24926             got, x, y, z, expected);
24927 
24928     ID3D12Resource_Release(dst_texture);
24929     ID3D12Resource_Release(src_buffer);
24930     ID3D12Resource_Release(zero_buffer);
24931     destroy_test_context(&context);
24932 }
24933 
test_copy_block_compressed_texture(void)24934 static void test_copy_block_compressed_texture(void)
24935 {
24936     D3D12_TEXTURE_COPY_LOCATION src_location, dst_location;
24937     ID3D12Resource *dst_buffer, *src_buffer;
24938     ID3D12GraphicsCommandList *command_list;
24939     struct test_context_desc desc;
24940     unsigned int x, y, block_id;
24941     struct test_context context;
24942     struct resource_readback rb;
24943     struct uvec4 got, expected;
24944     ID3D12CommandQueue *queue;
24945     ID3D12Resource *texture;
24946     ID3D12Device *device;
24947     unsigned int *ptr;
24948     D3D12_BOX box;
24949     HRESULT hr;
24950 
24951     memset(&desc, 0, sizeof(desc));
24952     desc.no_render_target = true;
24953     if (!init_test_context(&context, &desc))
24954         return;
24955     device = context.device;
24956     command_list = context.list;
24957     queue = context.queue;
24958 
24959     dst_buffer = create_default_buffer(device, 4096, 0, D3D12_RESOURCE_STATE_COPY_DEST);
24960     src_buffer = create_upload_buffer(device, 4096, NULL);
24961     hr = ID3D12Resource_Map(src_buffer, 0, NULL, (void **)&ptr);
24962     ok(hr == S_OK, "Failed to map buffer, hr %#x.\n", hr);
24963     for (x = 0; x < 4096 / format_size(DXGI_FORMAT_BC2_UNORM); ++x)
24964     {
24965         block_id = x << 8;
24966         *ptr++ = block_id | 0;
24967         *ptr++ = block_id | 1;
24968         *ptr++ = block_id | 2;
24969         *ptr++ = block_id | 3;
24970     }
24971     ID3D12Resource_Unmap(src_buffer, 0, NULL);
24972 
24973     texture = create_default_texture2d(device, 8, 8, 1, 4, DXGI_FORMAT_BC2_UNORM,
24974             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
24975 
24976     /* copy from buffer to texture */
24977     dst_location.pResource = texture;
24978     dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
24979     dst_location.SubresourceIndex = 0;
24980 
24981     src_location.pResource = src_buffer;
24982     src_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
24983     src_location.PlacedFootprint.Offset = 0;
24984     src_location.PlacedFootprint.Footprint.Format = DXGI_FORMAT_BC2_UNORM;
24985     src_location.PlacedFootprint.Footprint.Width = 32;
24986     src_location.PlacedFootprint.Footprint.Height = 32;
24987     src_location.PlacedFootprint.Footprint.Depth = 1;
24988     src_location.PlacedFootprint.Footprint.RowPitch
24989             = 32 / format_block_width(DXGI_FORMAT_BC2_UNORM) * format_size(DXGI_FORMAT_BC2_UNORM);
24990     src_location.PlacedFootprint.Footprint.RowPitch
24991             = align(src_location.PlacedFootprint.Footprint.RowPitch, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
24992 
24993     set_box(&box, 4, 4, 0, 8, 8, 1);
24994     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24995             &dst_location, 0, 0, 0, &src_location, &box);
24996     set_box(&box, 28, 0, 0, 32, 4, 1);
24997     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
24998             &dst_location, 4, 0, 0, &src_location, &box);
24999     set_box(&box, 0, 24, 0, 4, 28, 1);
25000     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
25001             &dst_location, 0, 4, 0, &src_location, &box);
25002     set_box(&box, 16, 16, 0, 20, 20, 1);
25003     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
25004             &dst_location, 4, 4, 0, &src_location, &box);
25005 
25006     /* miplevels smaller than 4x4 */
25007     dst_location.SubresourceIndex = 2;
25008     set_box(&box, 4, 0, 0, 8, 4, 1);
25009     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
25010             &dst_location, 0, 0, 0, &src_location, &box);
25011     dst_location.SubresourceIndex = 3;
25012     set_box(&box, 8, 0, 0, 12, 4, 1);
25013     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
25014             &dst_location, 0, 0, 0, &src_location, &box);
25015 
25016     transition_resource_state(command_list, texture,
25017             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
25018 
25019     /* copy from texture to buffer */
25020     dst_location.pResource = dst_buffer;
25021     dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
25022     dst_location.PlacedFootprint.Offset = 0;
25023     dst_location.PlacedFootprint.Footprint.Format = DXGI_FORMAT_BC2_UNORM;
25024     dst_location.PlacedFootprint.Footprint.Width = 8;
25025     dst_location.PlacedFootprint.Footprint.Height = 24;
25026     dst_location.PlacedFootprint.Footprint.Depth = 1;
25027     dst_location.PlacedFootprint.Footprint.RowPitch
25028             = 8 / format_block_width(DXGI_FORMAT_BC2_UNORM) * format_size(DXGI_FORMAT_BC2_UNORM);
25029     dst_location.PlacedFootprint.Footprint.RowPitch
25030             = align(dst_location.PlacedFootprint.Footprint.RowPitch, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
25031 
25032     src_location.pResource = texture;
25033     src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
25034     src_location.SubresourceIndex = 0;
25035 
25036     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
25037             &dst_location, 0, 0, 0, &src_location, NULL);
25038     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
25039             &dst_location, 0, 8, 0, &src_location, NULL);
25040     set_box(&box, 0, 0, 0, 8, 8, 1);
25041     ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
25042             &dst_location, 0, 16, 0, &src_location, &box);
25043 
25044     transition_resource_state(command_list, dst_buffer,
25045             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
25046 
25047     get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list);
25048     for (y = 0; y < 8 / format_block_height(DXGI_FORMAT_BC2_UNORM); ++y)
25049     {
25050         for (x = 0; x < 8 / format_block_width(DXGI_FORMAT_BC2_UNORM); ++x)
25051         {
25052             if (x == 0 && y == 0)
25053                 block_id = 33;
25054             else if (x == 1 && y == 0)
25055                 block_id = 7;
25056             else if (x == 0 && y == 1)
25057                 block_id = 192;
25058             else
25059                 block_id = 132;
25060 
25061             expected.x = block_id << 8 | 0;
25062             expected.y = block_id << 8 | 1;
25063             expected.z = block_id << 8 | 2;
25064             expected.w = block_id << 8 | 3;
25065             got = *get_readback_uvec4(&rb, x, y);
25066 
25067             if (!compare_uvec4(&got, &expected))
25068                 break;
25069         }
25070         if (!compare_uvec4(&got, &expected))
25071             break;
25072     }
25073     release_resource_readback(&rb);
25074     ok(compare_uvec4(&got, &expected),
25075             "Got {0x%08x, 0x%08x, 0x%08x, 0x%08x} at (%u, %u), expected {0x%08x, 0x%08x, 0x%08x, 0x%08x}.\n",
25076             got.x, got.y, got.z, got.w, x, y, expected.x, expected.y, expected.z, expected.w);
25077 
25078     reset_command_list(command_list, context.allocator);
25079     get_texture_readback_with_command_list(texture, 2, &rb, queue, command_list);
25080     block_id = 1;
25081     expected.x = block_id << 8 | 0;
25082     expected.y = block_id << 8 | 1;
25083     expected.z = block_id << 8 | 2;
25084     expected.w = block_id << 8 | 3;
25085     got = *get_readback_uvec4(&rb, 0, 0);
25086     release_resource_readback(&rb);
25087     ok(compare_uvec4(&got, &expected),
25088             "Got {0x%08x, 0x%08x, 0x%08x, 0x%08x}, expected {0x%08x, 0x%08x, 0x%08x, 0x%08x}.\n",
25089             got.x, got.y, got.z, got.w, expected.x, expected.y, expected.z, expected.w);
25090 
25091     reset_command_list(command_list, context.allocator);
25092     get_texture_readback_with_command_list(texture, 3, &rb, queue, command_list);
25093     block_id = 2;
25094     expected.x = block_id << 8 | 0;
25095     expected.y = block_id << 8 | 1;
25096     expected.z = block_id << 8 | 2;
25097     expected.w = block_id << 8 | 3;
25098     got = *get_readback_uvec4(&rb, 0, 0);
25099     release_resource_readback(&rb);
25100     ok(compare_uvec4(&got, &expected),
25101             "Got {0x%08x, 0x%08x, 0x%08x, 0x%08x}, expected {0x%08x, 0x%08x, 0x%08x, 0x%08x}.\n",
25102             got.x, got.y, got.z, got.w, expected.x, expected.y, expected.z, expected.w);
25103 
25104     reset_command_list(command_list, context.allocator);
25105     get_buffer_readback_with_command_list(dst_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
25106     for (y = 0; y < 24 / format_block_height(DXGI_FORMAT_BC2_UNORM); ++y)
25107     {
25108         unsigned int row_offset = dst_location.PlacedFootprint.Footprint.RowPitch / sizeof(got) * y;
25109 
25110         for (x = 0; x < 4 / format_block_width(DXGI_FORMAT_BC2_UNORM); ++x)
25111         {
25112             if (x == 0 && y % 2 == 0)
25113                 block_id = 33;
25114             else if (x == 1 && y % 2 == 0)
25115                 block_id = 7;
25116             else if (x == 0 && y % 2 == 1)
25117                 block_id = 192;
25118             else
25119                 block_id = 132;
25120 
25121             expected.x = block_id << 8 | 0;
25122             expected.y = block_id << 8 | 1;
25123             expected.z = block_id << 8 | 2;
25124             expected.w = block_id << 8 | 3;
25125             got = *get_readback_uvec4(&rb, x + row_offset, 0);
25126 
25127             if (!compare_uvec4(&got, &expected))
25128                 break;
25129         }
25130         if (!compare_uvec4(&got, &expected))
25131             break;
25132     }
25133     release_resource_readback(&rb);
25134     ok(compare_uvec4(&got, &expected),
25135             "Got {0x%08x, 0x%08x, 0x%08x, 0x%08x} at (%u, %u), expected {0x%08x, 0x%08x, 0x%08x, 0x%08x}.\n",
25136             got.x, got.y, got.z, got.w, x, y, expected.x, expected.y, expected.z, expected.w);
25137 
25138     ID3D12Resource_Release(texture);
25139     ID3D12Resource_Release(src_buffer);
25140     ID3D12Resource_Release(dst_buffer);
25141     destroy_test_context(&context);
25142 }
25143 
test_separate_bindings(void)25144 static void test_separate_bindings(void)
25145 {
25146     ID3D12Resource *cs_raw_buffer, *cs_raw_uav_buffer;
25147     ID3D12Resource *ps_raw_buffer, *ps_raw_uav_buffer;
25148     ID3D12Resource *cs_textures[2], *ps_textures[2];
25149     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
25150     D3D12_DESCRIPTOR_RANGE descriptor_ranges[2];
25151     ID3D12GraphicsCommandList *command_list;
25152     D3D12_ROOT_PARAMETER root_parameters[4];
25153     ID3D12PipelineState *compute_pso;
25154     ID3D12Resource *cs_cb, *ps_cb;
25155     struct test_context_desc desc;
25156     struct resource_readback rb;
25157     D3D12_SUBRESOURCE_DATA data;
25158     struct test_context context;
25159     ID3D12DescriptorHeap *heap;
25160     ID3D12CommandQueue *queue;
25161     ID3D12Device *device;
25162     unsigned int i;
25163     HRESULT hr;
25164 
25165     static const DWORD cs_code[] =
25166     {
25167 #if 0
25168         ByteAddressBuffer t0;
25169 
25170         RWByteAddressBuffer u1 : register(u1);
25171 
25172         cbuffer cb0
25173         {
25174             float4 cb0;
25175         };
25176 
25177         Texture2D t1;
25178         RWTexture2D<float> u2 : register(u2);
25179 
25180         [numthreads(1, 1, 1)]
25181         void main()
25182         {
25183             uint ret = 0xffffffff;
25184 
25185             if (t0.Load(0) != 2)
25186                 ret = 0;
25187             if (any(cb0 != float4(4, 8, 16, 32)))
25188                 ret = 0;
25189             if (any(t1.Load(0) != float4(4, 8, 16, 32)))
25190                 ret = 0;
25191             if (u2[(int2)0] != 4)
25192                 ret = 0;
25193 
25194             u1.Store(0, ret);
25195         }
25196 #endif
25197         0x43425844, 0x5ef0e316, 0x8a886806, 0x06279aa8, 0x10936fa5, 0x00000001, 0x000002bc, 0x00000003,
25198         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
25199         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000268, 0x00050050, 0x0000009a, 0x0100086a,
25200         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x030000a1, 0x00107000, 0x00000000, 0x04001858,
25201         0x00107000, 0x00000001, 0x00005555, 0x0300009d, 0x0011e000, 0x00000001, 0x0400189c, 0x0011e000,
25202         0x00000002, 0x00005555, 0x02000068, 0x00000002, 0x0400009b, 0x00000001, 0x00000001, 0x00000001,
25203         0x8c00002d, 0x800000c2, 0x00155543, 0x001000f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
25204         0x00000000, 0x00000000, 0x00107e46, 0x00000001, 0x0a000039, 0x001000f2, 0x00000000, 0x00100e46,
25205         0x00000000, 0x00004002, 0x40800000, 0x41000000, 0x41800000, 0x42000000, 0x0700003c, 0x00100032,
25206         0x00000000, 0x00100ae6, 0x00000000, 0x00100046, 0x00000000, 0x0700003c, 0x00100012, 0x00000000,
25207         0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0b000039, 0x001000f2, 0x00000001, 0x00208e46,
25208         0x00000000, 0x00000000, 0x00004002, 0x40800000, 0x41000000, 0x41800000, 0x42000000, 0x0700003c,
25209         0x00100062, 0x00000000, 0x00100ba6, 0x00000001, 0x00100106, 0x00000001, 0x0700003c, 0x00100022,
25210         0x00000000, 0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0700003c, 0x00100012, 0x00000000,
25211         0x0010000a, 0x00000000, 0x0010001a, 0x00000000, 0x8c0000a3, 0x800000c2, 0x00155543, 0x00100022,
25212         0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0011ee16, 0x00000002,
25213         0x07000039, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x40800000, 0x0700003c,
25214         0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x890000a5, 0x800002c2,
25215         0x00199983, 0x00100022, 0x00000000, 0x00004001, 0x00000000, 0x00107006, 0x00000000, 0x07000020,
25216         0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x00000002, 0x09000037, 0x00100012,
25217         0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x0010001a, 0x00000000, 0x070000a6,
25218         0x0011e012, 0x00000001, 0x00004001, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e,
25219     };
25220     static const DWORD ps_code[] =
25221     {
25222 #if 0
25223         ByteAddressBuffer t0;
25224 
25225         RWByteAddressBuffer u1 : register(u1);
25226 
25227         cbuffer cb0
25228         {
25229             float4 cb0;
25230         };
25231 
25232         Texture2D t1;
25233         RWTexture2D<float> u2 : register(u2);
25234 
25235         float4 main() : SV_Target0
25236         {
25237             bool ret = true;
25238 
25239             if (t0.Load(0) != 1)
25240                 ret = false;
25241             if (u1.Load(0) != 2)
25242                 ret = false;
25243             if (any(cb0 != float4(1, 2, 3, 4)))
25244                 ret = false;
25245             if (any(t1.Load(0) != float4(1, 2, 3, 4)))
25246                 ret = false;
25247             if (u2[(int2)0] != 1)
25248                 ret = false;
25249 
25250             return ret ? float4(0, 1, 0, 1) : float4(1, 0, 0, 1);
25251         }
25252 #endif
25253         0x43425844, 0xb5db404c, 0xd1dd05ca, 0xf5c1284d, 0x58d71b13, 0x00000001, 0x00000358, 0x00000003,
25254         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
25255         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
25256         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000002e0, 0x00000050, 0x000000b8,
25257         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x030000a1, 0x00107000, 0x00000000,
25258         0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x0300009d, 0x0011e000, 0x00000001, 0x0400189c,
25259         0x0011e000, 0x00000002, 0x00005555, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002,
25260         0x0b000039, 0x001000f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00004002, 0x3f800000,
25261         0x40000000, 0x40400000, 0x40800000, 0x0700003c, 0x00100032, 0x00000000, 0x00100ae6, 0x00000000,
25262         0x00100046, 0x00000000, 0x0700003c, 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a,
25263         0x00000000, 0x890000a5, 0x800002c2, 0x00199983, 0x00100022, 0x00000000, 0x00004001, 0x00000000,
25264         0x0011e006, 0x00000001, 0x07000027, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001,
25265         0x00000002, 0x0700003c, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010001a, 0x00000000,
25266         0x8c00002d, 0x800000c2, 0x00155543, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000,
25267         0x00000000, 0x00000000, 0x00107e46, 0x00000001, 0x0a000039, 0x001000f2, 0x00000001, 0x00100e46,
25268         0x00000001, 0x00004002, 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 0x0700003c, 0x00100062,
25269         0x00000000, 0x00100ba6, 0x00000001, 0x00100106, 0x00000001, 0x0700003c, 0x00100022, 0x00000000,
25270         0x0010002a, 0x00000000, 0x0010001a, 0x00000000, 0x0700003c, 0x00100012, 0x00000000, 0x0010001a,
25271         0x00000000, 0x0010000a, 0x00000000, 0x8c0000a3, 0x800000c2, 0x00155543, 0x00100022, 0x00000000,
25272         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0011ee16, 0x00000002, 0x07000039,
25273         0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x3f800000, 0x0700003c, 0x00100012,
25274         0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x890000a5, 0x800002c2, 0x00199983,
25275         0x00100022, 0x00000000, 0x00004001, 0x00000000, 0x00107006, 0x00000000, 0x07000020, 0x00100022,
25276         0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0x00000001, 0x09000037, 0x00100012, 0x00000000,
25277         0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x0010001a, 0x00000000, 0x0f000037, 0x001020f2,
25278         0x00000000, 0x00100006, 0x00000000, 0x00004002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000,
25279         0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e,
25280     };
25281     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
25282     static const struct vec4 cs_data = {4.0f, 8.0f, 16.0f, 32.0f};
25283     static const struct vec4 ps_data = {1.0f, 2.0f, 3.0f, 4.0f};
25284     static const float cs_texture_data = 4.0f;
25285     static const float ps_texture_data = 1.0f;
25286     static const uint32_t cs_raw_data = 2;
25287     static const uint32_t ps_raw_data = 1;
25288     static const uint32_t ps_raw_uav_data = 2;
25289     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
25290 
25291     memset(&desc, 0, sizeof(desc));
25292     desc.no_root_signature = true;
25293     if (!init_test_context(&context, &desc))
25294         return;
25295     device = context.device;
25296     command_list = context.list;
25297     queue = context.queue;
25298 
25299     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
25300     root_parameters[0].Descriptor.ShaderRegister = 0;
25301     root_parameters[0].Descriptor.RegisterSpace = 0;
25302     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
25303     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
25304     root_parameters[1].Descriptor.ShaderRegister = 0;
25305     root_parameters[1].Descriptor.RegisterSpace = 0;
25306     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
25307     root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
25308     root_parameters[2].Descriptor.ShaderRegister = 1;
25309     root_parameters[2].Descriptor.RegisterSpace = 0;
25310     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
25311     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
25312     descriptor_ranges[0].NumDescriptors = 1;
25313     descriptor_ranges[0].BaseShaderRegister = 1;
25314     descriptor_ranges[0].RegisterSpace = 0;
25315     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
25316     descriptor_ranges[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
25317     descriptor_ranges[1].NumDescriptors = 1;
25318     descriptor_ranges[1].BaseShaderRegister = 2;
25319     descriptor_ranges[1].RegisterSpace = 0;
25320     descriptor_ranges[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
25321     root_parameters[3].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
25322     root_parameters[3].DescriptorTable.NumDescriptorRanges = 2;
25323     root_parameters[3].DescriptorTable.pDescriptorRanges = descriptor_ranges;
25324     root_parameters[3].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
25325     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
25326     root_signature_desc.NumParameters = 4;
25327     root_signature_desc.pParameters = root_parameters;
25328     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
25329     ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
25330 
25331     compute_pso = create_compute_pipeline_state(device, context.root_signature,
25332             shader_bytecode(cs_code, sizeof(cs_code)));
25333 
25334     context.pipeline_state = create_pipeline_state(device,
25335             context.root_signature, context.render_target_desc.Format,
25336             NULL, &ps, NULL);
25337 
25338     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 20);
25339 
25340     cs_cb = create_upload_buffer(device, sizeof(cs_data), &cs_data);
25341     ps_cb = create_upload_buffer(device, sizeof(ps_data), &ps_data);
25342 
25343     cs_raw_buffer = create_upload_buffer(device, sizeof(cs_raw_data), &cs_raw_data);
25344     ps_raw_buffer = create_upload_buffer(device, sizeof(ps_raw_data), &ps_raw_data);
25345 
25346     cs_raw_uav_buffer = create_default_buffer(device, sizeof(uint32_t),
25347             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
25348     ps_raw_uav_buffer = create_default_buffer(device, sizeof(ps_raw_uav_data),
25349             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
25350     upload_buffer_data(ps_raw_uav_buffer, 0, sizeof(ps_raw_uav_data), &ps_raw_uav_data, queue, command_list);
25351     reset_command_list(command_list, context.allocator);
25352     transition_resource_state(command_list, ps_raw_uav_buffer,
25353             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
25354 
25355     cs_textures[0] = create_default_texture(device,
25356             1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
25357     data.pData = &cs_data;
25358     data.RowPitch = sizeof(cs_data);
25359     data.SlicePitch = data.RowPitch;
25360     upload_texture_data(cs_textures[0], &data, 1, queue, command_list);
25361     reset_command_list(command_list, context.allocator);
25362     transition_resource_state(command_list, cs_textures[0],
25363             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
25364     cs_textures[1] = create_default_texture(device, 1, 1, DXGI_FORMAT_R32_FLOAT,
25365             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
25366     data.pData = &cs_texture_data;
25367     data.RowPitch = sizeof(cs_texture_data);
25368     data.SlicePitch = data.RowPitch;
25369     upload_texture_data(cs_textures[1], &data, 1, queue, command_list);
25370     reset_command_list(command_list, context.allocator);
25371     transition_resource_state(command_list, cs_textures[1],
25372             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
25373 
25374     ps_textures[0] = create_default_texture(device,
25375             1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
25376     data.pData = &ps_data;
25377     data.RowPitch = sizeof(ps_data);
25378     data.SlicePitch = data.RowPitch;
25379     upload_texture_data(ps_textures[0], &data, 1, queue, command_list);
25380     reset_command_list(command_list, context.allocator);
25381     transition_resource_state(command_list, ps_textures[0],
25382             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
25383     ps_textures[1] = create_default_texture(device, 1, 1, DXGI_FORMAT_R32_FLOAT,
25384             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
25385     data.pData = &ps_texture_data;
25386     data.RowPitch = sizeof(ps_texture_data);
25387     data.SlicePitch = data.RowPitch;
25388     upload_texture_data(ps_textures[1], &data, 1, queue, command_list);
25389     reset_command_list(command_list, context.allocator);
25390     transition_resource_state(command_list, ps_textures[1],
25391             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
25392 
25393     ID3D12Device_CreateShaderResourceView(device, cs_textures[0], NULL,
25394             get_cpu_descriptor_handle(&context, heap, 0));
25395     ID3D12Device_CreateUnorderedAccessView(device, cs_textures[1], NULL, NULL,
25396             get_cpu_descriptor_handle(&context, heap, 1));
25397 
25398     ID3D12Device_CreateShaderResourceView(device, ps_textures[0], NULL,
25399             get_cpu_descriptor_handle(&context, heap, 10));
25400     ID3D12Device_CreateUnorderedAccessView(device, ps_textures[1], NULL, NULL,
25401             get_cpu_descriptor_handle(&context, heap, 11));
25402 
25403     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
25404     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
25405     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
25406     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
25407 
25408     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
25409     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
25410     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
25411 
25412     ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(command_list,
25413             0, ID3D12Resource_GetGPUVirtualAddress(cs_cb));
25414     ID3D12GraphicsCommandList_SetComputeRootShaderResourceView(command_list,
25415             1, ID3D12Resource_GetGPUVirtualAddress(cs_raw_buffer));
25416     ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list,
25417             2, ID3D12Resource_GetGPUVirtualAddress(cs_raw_uav_buffer));
25418     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
25419             3, get_gpu_descriptor_handle(&context, heap, 0));
25420 
25421     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list,
25422             0, ID3D12Resource_GetGPUVirtualAddress(ps_cb));
25423     ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(command_list,
25424             1, ID3D12Resource_GetGPUVirtualAddress(ps_raw_buffer));
25425     ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView(command_list,
25426             2, ID3D12Resource_GetGPUVirtualAddress(ps_raw_uav_buffer));
25427     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list,
25428             3, get_gpu_descriptor_handle(&context, heap, 10));
25429 
25430     ID3D12GraphicsCommandList_SetPipelineState(command_list, compute_pso);
25431     ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
25432 
25433     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
25434     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
25435     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
25436 
25437     transition_resource_state(command_list, context.render_target,
25438             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
25439     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
25440     reset_command_list(command_list, context.allocator);
25441     transition_resource_state(command_list, cs_raw_uav_buffer,
25442             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
25443     get_buffer_readback_with_command_list(cs_raw_uav_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
25444     check_readback_data_uint(&rb, NULL, 0xffffffff, 0);
25445     release_resource_readback(&rb);
25446 
25447     ID3D12Resource_Release(cs_cb);
25448     ID3D12Resource_Release(ps_cb);
25449     ID3D12Resource_Release(cs_raw_buffer);
25450     ID3D12Resource_Release(cs_raw_uav_buffer);
25451     ID3D12Resource_Release(ps_raw_buffer);
25452     ID3D12Resource_Release(ps_raw_uav_buffer);
25453     for (i = 0; i < ARRAY_SIZE(cs_textures); ++i)
25454         ID3D12Resource_Release(cs_textures[i]);
25455     for (i = 0; i < ARRAY_SIZE(ps_textures); ++i)
25456         ID3D12Resource_Release(ps_textures[i]);
25457     ID3D12DescriptorHeap_Release(heap);
25458     ID3D12PipelineState_Release(compute_pso);
25459     destroy_test_context(&context);
25460 }
25461 
test_face_culling(void)25462 static void test_face_culling(void)
25463 {
25464     ID3D12PipelineState *color_pso, *ccw_color_pso, *pso;
25465     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
25466     ID3D12GraphicsCommandList *command_list;
25467     struct test_context_desc desc;
25468     struct test_context context;
25469     ID3D12CommandQueue *queue;
25470     ID3D12Device *device;
25471     unsigned int i;
25472     HRESULT hr;
25473 
25474     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
25475     static const struct vec4 green = {0.0f, 1.0f, 0.0f, 1.0f};
25476     static const DWORD vs_ccw_code[] =
25477     {
25478 #if 0
25479         void main(uint id : SV_VertexID, out float4 position : SV_Position)
25480         {
25481             float2 coords = float2((id << 1) & 2, id & 2);
25482             position = float4(coords * float2(2, 2) + float2(-1, -1), 0, 1);
25483         }
25484 #endif
25485         0x43425844, 0xdcd52e92, 0x3f4a3922, 0xa376c4ed, 0x2bc626c0, 0x00000001, 0x0000018c, 0x00000003,
25486         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
25487         0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000101, 0x565f5653, 0x65747265, 0x00444978,
25488         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
25489         0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x58454853, 0x000000f0, 0x00010050,
25490         0x0000003c, 0x0100086a, 0x04000060, 0x00101012, 0x00000000, 0x00000006, 0x04000067, 0x001020f2,
25491         0x00000000, 0x00000001, 0x02000068, 0x00000001, 0x0b00008c, 0x00100012, 0x00000000, 0x00004001,
25492         0x00000001, 0x00004001, 0x00000001, 0x0010100a, 0x00000000, 0x00004001, 0x00000000, 0x07000001,
25493         0x00100042, 0x00000000, 0x0010100a, 0x00000000, 0x00004001, 0x00000002, 0x05000056, 0x00100032,
25494         0x00000000, 0x00100086, 0x00000000, 0x0f000032, 0x00102032, 0x00000000, 0x00100046, 0x00000000,
25495         0x00004002, 0x40000000, 0x40000000, 0x00000000, 0x00000000, 0x00004002, 0xbf800000, 0xbf800000,
25496         0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
25497         0x00000000, 0x3f800000, 0x0100003e,
25498     };
25499     static const D3D12_SHADER_BYTECODE vs_ccw = {vs_ccw_code, sizeof(vs_ccw_code)};
25500     static const DWORD ps_color_code[] =
25501     {
25502 #if 0
25503         float4 color;
25504 
25505         float4 main(float4 position : SV_POSITION) : SV_Target
25506         {
25507             return color;
25508         }
25509 #endif
25510         0x43425844, 0xd18ead43, 0x8b8264c1, 0x9c0a062d, 0xfc843226, 0x00000001, 0x000000e0, 0x00000003,
25511         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
25512         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49,
25513         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
25514         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000044, 0x00000050,
25515         0x00000011, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2,
25516         0x00000000, 0x06000036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e,
25517     };
25518     static const D3D12_SHADER_BYTECODE ps_color = {ps_color_code, sizeof(ps_color_code)};
25519     static const DWORD ps_front_code[] =
25520     {
25521 #if 0
25522         float4 main(uint front : SV_IsFrontFace) : SV_Target
25523         {
25524             return (front == ~0u) ? float4(0.0f, 1.0f, 0.0f, 1.0f) : float4(0.0f, 0.0f, 1.0f, 1.0f);
25525         }
25526 #endif
25527         0x43425844, 0x92002fad, 0xc5c620b9, 0xe7a154fb, 0x78b54e63, 0x00000001, 0x00000128, 0x00000003,
25528         0x0000002c, 0x00000064, 0x00000098, 0x4e475349, 0x00000030, 0x00000001, 0x00000008, 0x00000020,
25529         0x00000000, 0x00000009, 0x00000001, 0x00000000, 0x00000101, 0x495f5653, 0x6f724673, 0x6146746e,
25530         0xab006563, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
25531         0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000088,
25532         0x00000040, 0x00000022, 0x04000863, 0x00101012, 0x00000000, 0x00000009, 0x03000065, 0x001020f2,
25533         0x00000000, 0x02000068, 0x00000001, 0x07000020, 0x00100012, 0x00000000, 0x0010100a, 0x00000000,
25534         0x00004001, 0xffffffff, 0x0f000037, 0x001020f2, 0x00000000, 0x00100006, 0x00000000, 0x00004002,
25535         0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x00004002, 0x00000000, 0x00000000, 0x3f800000,
25536         0x3f800000, 0x0100003e,
25537     };
25538     static const D3D12_SHADER_BYTECODE ps_front = {ps_front_code, sizeof(ps_front_code)};
25539     static const struct
25540     {
25541         D3D12_CULL_MODE cull_mode;
25542         bool front_ccw;
25543         bool expected_cw;
25544         bool expected_ccw;
25545     }
25546     tests[] =
25547     {
25548         {D3D12_CULL_MODE_NONE,  false, true,  true},
25549         {D3D12_CULL_MODE_NONE,  true,  true,  true},
25550         {D3D12_CULL_MODE_FRONT, false, false, true},
25551         {D3D12_CULL_MODE_FRONT, true,  true,  false},
25552         {D3D12_CULL_MODE_BACK,  false, true,  false},
25553         {D3D12_CULL_MODE_BACK,  true,  false, true},
25554     };
25555     static const bool front_tests[] = {false, true};
25556 
25557     memset(&desc, 0, sizeof(desc));
25558     desc.no_root_signature = true;
25559     if (!init_test_context(&context, &desc))
25560         return;
25561     device = context.device;
25562     command_list = context.list;
25563     queue = context.queue;
25564 
25565     context.root_signature = create_32bit_constants_root_signature(device,
25566             0, 4, D3D12_SHADER_VISIBILITY_PIXEL);
25567 
25568     color_pso = create_pipeline_state(device, context.root_signature,
25569             context.render_target_desc.Format, NULL, &ps_color, NULL);
25570     ccw_color_pso = create_pipeline_state(device, context.root_signature,
25571             context.render_target_desc.Format, &vs_ccw, &ps_color, NULL);
25572 
25573     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
25574     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
25575     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
25576     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
25577     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
25578     ID3D12GraphicsCommandList_SetPipelineState(command_list, color_pso);
25579     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
25580     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &green.x, 0);
25581     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
25582 
25583     transition_resource_state(command_list, context.render_target,
25584             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
25585     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
25586     reset_command_list(command_list, context.allocator);
25587     transition_resource_state(command_list, context.render_target,
25588             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
25589 
25590     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
25591     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
25592     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
25593     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
25594     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
25595     ID3D12GraphicsCommandList_SetPipelineState(command_list, ccw_color_pso);
25596     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
25597     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &green.x, 0);
25598     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
25599 
25600     transition_resource_state(command_list, context.render_target,
25601             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
25602     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xffffffff, 0);
25603     reset_command_list(command_list, context.allocator);
25604     transition_resource_state(command_list, context.render_target,
25605             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
25606 
25607     for (i = 0; i < ARRAY_SIZE(tests); ++i)
25608     {
25609         vkd3d_test_set_context("Test %u", i);
25610 
25611         init_pipeline_state_desc(&pso_desc, context.root_signature,
25612                 context.render_target_desc.Format, NULL, &ps_color, NULL);
25613         pso_desc.RasterizerState.CullMode = tests[i].cull_mode;
25614         pso_desc.RasterizerState.FrontCounterClockwise = tests[i].front_ccw;
25615         hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
25616                 &IID_ID3D12PipelineState, (void **)&pso);
25617         ok(SUCCEEDED(hr), "Failed to create graphics pipeline state, hr %#x.\n", hr);
25618 
25619         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
25620         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
25621         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
25622         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
25623         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
25624         ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
25625         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
25626         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &green.x, 0);
25627         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
25628 
25629         transition_resource_state(command_list, context.render_target,
25630                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
25631         check_sub_resource_uint(context.render_target, 0, queue, command_list,
25632                 tests[i].expected_cw ? 0xff00ff00 : 0xffffffff, 0);
25633         reset_command_list(command_list, context.allocator);
25634         transition_resource_state(command_list, context.render_target,
25635                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
25636 
25637         ID3D12PipelineState_Release(pso);
25638         pso_desc.VS = vs_ccw;
25639         hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
25640                 &IID_ID3D12PipelineState, (void **)&pso);
25641         ok(SUCCEEDED(hr), "Failed to create graphics pipeline state, hr %#x.\n", hr);
25642 
25643         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
25644         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
25645         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
25646         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
25647         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
25648         ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
25649         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
25650         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &green.x, 0);
25651         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
25652 
25653         transition_resource_state(command_list, context.render_target,
25654                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
25655         check_sub_resource_uint(context.render_target, 0, queue, command_list,
25656                 tests[i].expected_ccw ? 0xff00ff00 : 0xffffffff, 0);
25657         reset_command_list(command_list, context.allocator);
25658         transition_resource_state(command_list, context.render_target,
25659                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
25660 
25661         ID3D12PipelineState_Release(pso);
25662     }
25663     vkd3d_test_set_context(NULL);
25664 
25665     /* Test SV_IsFrontFace. */
25666     for (i = 0; i < ARRAY_SIZE(front_tests); ++i)
25667     {
25668         vkd3d_test_set_context("Test %u", i);
25669 
25670         init_pipeline_state_desc(&pso_desc, context.root_signature,
25671                 context.render_target_desc.Format, NULL, &ps_front, NULL);
25672         pso_desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
25673         pso_desc.RasterizerState.FrontCounterClockwise = front_tests[i];
25674         hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
25675                 &IID_ID3D12PipelineState, (void **)&pso);
25676         ok(SUCCEEDED(hr), "Failed to create graphics pipeline state, hr %#x.\n", hr);
25677 
25678         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
25679         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
25680         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
25681         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
25682         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
25683         ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
25684         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
25685         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
25686 
25687         transition_resource_state(command_list, context.render_target,
25688                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
25689         check_sub_resource_uint(context.render_target, 0, queue, command_list,
25690                 front_tests[i] ? 0xffff0000 : 0xff00ff00, 0);
25691         reset_command_list(command_list, context.allocator);
25692         transition_resource_state(command_list, context.render_target,
25693                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
25694 
25695         ID3D12PipelineState_Release(pso);
25696         pso_desc.VS = vs_ccw;
25697         hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
25698                 &IID_ID3D12PipelineState, (void **)&pso);
25699         ok(SUCCEEDED(hr), "Failed to create graphics pipeline state, hr %#x.\n", hr);
25700 
25701         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
25702         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
25703         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
25704         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
25705         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
25706         ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
25707         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
25708         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
25709 
25710         transition_resource_state(command_list, context.render_target,
25711                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
25712         check_sub_resource_uint(context.render_target, 0, queue, command_list,
25713                 front_tests[i] ? 0xff00ff00 : 0xffff0000, 0);
25714         reset_command_list(command_list, context.allocator);
25715         transition_resource_state(command_list, context.render_target,
25716                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
25717 
25718         ID3D12PipelineState_Release(pso);
25719     }
25720     vkd3d_test_set_context(NULL);
25721 
25722     ID3D12PipelineState_Release(color_pso);
25723     ID3D12PipelineState_Release(ccw_color_pso);
25724     destroy_test_context(&context);
25725 }
25726 
draw_thread_main(void * thread_data)25727 static void draw_thread_main(void *thread_data)
25728 {
25729     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
25730     struct test_context *context = thread_data;
25731     ID3D12GraphicsCommandList *command_list;
25732     ID3D12CommandAllocator *allocator;
25733     D3D12_CPU_DESCRIPTOR_HANDLE rtv;
25734     ID3D12Resource *render_target;
25735     ID3D12DescriptorHeap *heap;
25736     ID3D12CommandQueue *queue;
25737     ID3D12Device *device;
25738     unsigned int i;
25739     HRESULT hr;
25740 
25741     queue = context->queue;
25742     device = context->device;
25743     heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1);
25744     rtv = get_cpu_descriptor_handle(context, heap, 0);
25745     create_render_target(context, NULL, &render_target, &rtv);
25746 
25747     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
25748             &IID_ID3D12CommandAllocator, (void **)&allocator);
25749     ok(SUCCEEDED(hr), "Failed to create command allocator, hr %#x.\n", hr);
25750     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
25751             allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&command_list);
25752     ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
25753 
25754     for (i = 0; i < 100; ++i)
25755     {
25756         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv, white, 0, NULL);
25757         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &rtv, false, NULL);
25758         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context->root_signature);
25759         ID3D12GraphicsCommandList_SetPipelineState(command_list, context->pipeline_state);
25760         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
25761         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context->viewport);
25762         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context->scissor_rect);
25763         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
25764 
25765         transition_resource_state(command_list, render_target,
25766                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
25767         check_sub_resource_uint(render_target, 0, queue, command_list, 0xff00ff00, 0);
25768         reset_command_list(command_list, allocator);
25769         transition_resource_state(command_list, render_target,
25770                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
25771     }
25772 
25773     ID3D12DescriptorHeap_Release(heap);
25774     ID3D12Resource_Release(render_target);
25775     ID3D12CommandAllocator_Release(allocator);
25776     ID3D12GraphicsCommandList_Release(command_list);
25777 }
25778 
test_multithread_command_queue_exec(void)25779 static void test_multithread_command_queue_exec(void)
25780 {
25781     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
25782     ID3D12GraphicsCommandList *command_list;
25783     struct test_context context;
25784     ID3D12CommandQueue *queue;
25785     HANDLE threads[10];
25786     unsigned int i;
25787 
25788     if (!init_test_context(&context, NULL))
25789         return;
25790     command_list = context.list;
25791     queue = context.queue;
25792 
25793     for (i = 0; i < ARRAY_SIZE(threads); ++i)
25794     {
25795         threads[i] = create_thread(draw_thread_main, &context);
25796         ok(threads[i], "Failed to create thread %u.\n", i);
25797     }
25798 
25799     for (i = 0; i < 100; ++i)
25800     {
25801         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
25802         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
25803         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
25804         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
25805         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
25806         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
25807         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
25808         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
25809 
25810         transition_resource_state(command_list, context.render_target,
25811                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
25812         check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
25813         reset_command_list(command_list, context.allocator);
25814         transition_resource_state(command_list, context.render_target,
25815                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
25816     }
25817 
25818     for (i = 0; i < ARRAY_SIZE(threads); ++i)
25819         ok(join_thread(threads[i]), "Failed to join thread %u.\n", i);
25820 
25821     destroy_test_context(&context);
25822 }
25823 
test_geometry_shader(void)25824 static void test_geometry_shader(void)
25825 {
25826     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
25827     ID3D12GraphicsCommandList *command_list;
25828     D3D12_INPUT_LAYOUT_DESC input_layout;
25829     D3D12_CPU_DESCRIPTOR_HANDLE rtvs[2];
25830     ID3D12PipelineState *pso_5_0, *pso;
25831     struct test_context_desc desc;
25832     D3D12_VERTEX_BUFFER_VIEW vbv;
25833     struct resource_readback rb;
25834     struct test_context context;
25835     ID3D12CommandQueue *queue;
25836     ID3D12Resource *texture;
25837     ID3D12Device *device;
25838     ID3D12Resource *vb;
25839     unsigned int color;
25840     unsigned int i;
25841     HRESULT hr;
25842 
25843     static const float red[] = {1.0f, 0.0f, 0.0f, 1.0f};
25844     static const struct
25845     {
25846         struct vec4 position;
25847         unsigned int color;
25848     }
25849     vertex[] =
25850     {
25851         {{0.0f, 0.0f, 1.0f, 1.0f}, 0xffffff00},
25852     };
25853     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
25854     {
25855         {"SV_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0,  0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
25856         {"COLOR",       0, DXGI_FORMAT_R8G8B8A8_UNORM,     0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
25857     };
25858 #if 0
25859     struct vs_data
25860     {
25861         float4 pos : SV_POSITION;
25862         float4 color : COLOR;
25863     };
25864 
25865     void main(in struct vs_data vs_input, out struct vs_data vs_output)
25866     {
25867         vs_output.pos = vs_input.pos;
25868         vs_output.color = vs_input.color;
25869     }
25870 #endif
25871     static const DWORD vs_code[] =
25872     {
25873         0x43425844, 0xd5b32785, 0x35332906, 0x4d05e031, 0xf66a58af, 0x00000001, 0x00000144, 0x00000003,
25874         0x0000002c, 0x00000080, 0x000000d4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
25875         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000044, 0x00000000, 0x00000000,
25876         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
25877         0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003,
25878         0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
25879         0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x52444853, 0x00000068, 0x00010040,
25880         0x0000001a, 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x001010f2, 0x00000001, 0x04000067,
25881         0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x001020f2,
25882         0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x001020f2, 0x00000001, 0x00101e46, 0x00000001,
25883         0x0100003e,
25884     };
25885     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
25886 #if 0
25887     struct gs_data
25888     {
25889         float4 pos : SV_POSITION;
25890         float4 color : COLOR;
25891     };
25892 
25893     [maxvertexcount(4)]
25894     void main(point struct gs_data vin[1], inout TriangleStream<gs_data> vout)
25895     {
25896         float offset = 0.2 * vin[0].pos.w;
25897         gs_data v;
25898 
25899         v.color = vin[0].color;
25900 
25901         v.pos = float4(vin[0].pos.x - offset, vin[0].pos.y - offset, vin[0].pos.z, 1.0);
25902         vout.Append(v);
25903         v.pos = float4(vin[0].pos.x - offset, vin[0].pos.y + offset, vin[0].pos.z, 1.0);
25904         vout.Append(v);
25905         v.pos = float4(vin[0].pos.x + offset, vin[0].pos.y - offset, vin[0].pos.z, 1.0);
25906         vout.Append(v);
25907         v.pos = float4(vin[0].pos.x + offset, vin[0].pos.y + offset, vin[0].pos.z, 1.0);
25908         vout.Append(v);
25909     }
25910 #endif
25911     static const DWORD gs_code[] =
25912     {
25913         0x43425844, 0x70616045, 0x96756e1f, 0x1caeecb8, 0x3749528c, 0x00000001, 0x0000034c, 0x00000003,
25914         0x0000002c, 0x00000080, 0x000000d4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
25915         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x00000044, 0x00000000, 0x00000000,
25916         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
25917         0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003,
25918         0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
25919         0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x52444853, 0x00000270, 0x00020040,
25920         0x0000009c, 0x05000061, 0x002010f2, 0x00000001, 0x00000000, 0x00000001, 0x0400005f, 0x002010f2,
25921         0x00000001, 0x00000001, 0x02000068, 0x00000001, 0x0100085d, 0x0100285c, 0x04000067, 0x001020f2,
25922         0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x0200005e, 0x00000004, 0x0f000032,
25923         0x00100032, 0x00000000, 0x80201ff6, 0x00000041, 0x00000000, 0x00000000, 0x00004002, 0x3e4ccccd,
25924         0x3e4ccccd, 0x00000000, 0x00000000, 0x00201046, 0x00000000, 0x00000000, 0x05000036, 0x00102032,
25925         0x00000000, 0x00100046, 0x00000000, 0x06000036, 0x00102042, 0x00000000, 0x0020102a, 0x00000000,
25926         0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x00004001, 0x3f800000, 0x06000036, 0x001020f2,
25927         0x00000001, 0x00201e46, 0x00000000, 0x00000001, 0x01000013, 0x05000036, 0x00102012, 0x00000000,
25928         0x0010000a, 0x00000000, 0x0e000032, 0x00100052, 0x00000000, 0x00201ff6, 0x00000000, 0x00000000,
25929         0x00004002, 0x3e4ccccd, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00201106, 0x00000000, 0x00000000,
25930         0x05000036, 0x00102022, 0x00000000, 0x0010002a, 0x00000000, 0x06000036, 0x00102042, 0x00000000,
25931         0x0020102a, 0x00000000, 0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x00004001, 0x3f800000,
25932         0x06000036, 0x001020f2, 0x00000001, 0x00201e46, 0x00000000, 0x00000001, 0x01000013, 0x05000036,
25933         0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x05000036, 0x00102022, 0x00000000, 0x0010001a,
25934         0x00000000, 0x06000036, 0x00102042, 0x00000000, 0x0020102a, 0x00000000, 0x00000000, 0x05000036,
25935         0x00102082, 0x00000000, 0x00004001, 0x3f800000, 0x06000036, 0x001020f2, 0x00000001, 0x00201e46,
25936         0x00000000, 0x00000001, 0x01000013, 0x05000036, 0x00102032, 0x00000000, 0x00100086, 0x00000000,
25937         0x06000036, 0x00102042, 0x00000000, 0x0020102a, 0x00000000, 0x00000000, 0x05000036, 0x00102082,
25938         0x00000000, 0x00004001, 0x3f800000, 0x06000036, 0x001020f2, 0x00000001, 0x00201e46, 0x00000000,
25939         0x00000001, 0x01000013, 0x0100003e,
25940     };
25941     static const D3D12_SHADER_BYTECODE gs = {gs_code, sizeof(gs_code)};
25942     static const DWORD gs_5_0_code[] =
25943     {
25944         0x43425844, 0x57251c23, 0x4971d115, 0x8fee0b13, 0xba149ea1, 0x00000001, 0x00000384, 0x00000003,
25945         0x0000002c, 0x00000080, 0x000000dc, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
25946         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x00000044, 0x00000000, 0x00000000,
25947         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
25948         0x3547534f, 0x00000054, 0x00000002, 0x00000008, 0x00000000, 0x00000040, 0x00000000, 0x00000001,
25949         0x00000003, 0x00000000, 0x0000000f, 0x00000000, 0x0000004c, 0x00000000, 0x00000000, 0x00000003,
25950         0x00000001, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x58454853,
25951         0x000002a0, 0x00020050, 0x000000a8, 0x0100086a, 0x05000061, 0x002010f2, 0x00000001, 0x00000000,
25952         0x00000001, 0x0400005f, 0x002010f2, 0x00000001, 0x00000001, 0x02000068, 0x00000001, 0x0100085d,
25953         0x0300008f, 0x00110000, 0x00000000, 0x0100285c, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
25954         0x03000065, 0x001020f2, 0x00000001, 0x0200005e, 0x00000004, 0x0f000032, 0x00100032, 0x00000000,
25955         0x80201ff6, 0x00000041, 0x00000000, 0x00000000, 0x00004002, 0x3e4ccccd, 0x3e4ccccd, 0x00000000,
25956         0x00000000, 0x00201046, 0x00000000, 0x00000000, 0x05000036, 0x00102032, 0x00000000, 0x00100046,
25957         0x00000000, 0x06000036, 0x00102042, 0x00000000, 0x0020102a, 0x00000000, 0x00000000, 0x05000036,
25958         0x00102082, 0x00000000, 0x00004001, 0x3f800000, 0x06000036, 0x001020f2, 0x00000001, 0x00201e46,
25959         0x00000000, 0x00000001, 0x03000075, 0x00110000, 0x00000000, 0x05000036, 0x00102012, 0x00000000,
25960         0x0010000a, 0x00000000, 0x0e000032, 0x00100052, 0x00000000, 0x00201ff6, 0x00000000, 0x00000000,
25961         0x00004002, 0x3e4ccccd, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00201106, 0x00000000, 0x00000000,
25962         0x05000036, 0x00102022, 0x00000000, 0x0010002a, 0x00000000, 0x06000036, 0x00102042, 0x00000000,
25963         0x0020102a, 0x00000000, 0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x00004001, 0x3f800000,
25964         0x06000036, 0x001020f2, 0x00000001, 0x00201e46, 0x00000000, 0x00000001, 0x03000075, 0x00110000,
25965         0x00000000, 0x05000036, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x05000036, 0x00102022,
25966         0x00000000, 0x0010001a, 0x00000000, 0x06000036, 0x00102042, 0x00000000, 0x0020102a, 0x00000000,
25967         0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x00004001, 0x3f800000, 0x06000036, 0x001020f2,
25968         0x00000001, 0x00201e46, 0x00000000, 0x00000001, 0x03000075, 0x00110000, 0x00000000, 0x05000036,
25969         0x00102032, 0x00000000, 0x00100086, 0x00000000, 0x06000036, 0x00102042, 0x00000000, 0x0020102a,
25970         0x00000000, 0x00000000, 0x05000036, 0x00102082, 0x00000000, 0x00004001, 0x3f800000, 0x06000036,
25971         0x001020f2, 0x00000001, 0x00201e46, 0x00000000, 0x00000001, 0x03000075, 0x00110000, 0x00000000,
25972         0x0100003e,
25973     };
25974     static const D3D12_SHADER_BYTECODE gs_5_0 = {gs_5_0_code, sizeof(gs_5_0_code)};
25975 #if 0
25976     struct ps_data
25977     {
25978         float4 pos : SV_POSITION;
25979         float4 color : COLOR;
25980     };
25981 
25982     float4 main(struct ps_data ps_input) : SV_Target
25983     {
25984         return ps_input.color;
25985     }
25986 #endif
25987     static const DWORD ps_code[] =
25988     {
25989         0x43425844, 0x89803e59, 0x3f798934, 0xf99181df, 0xf5556512, 0x00000001, 0x000000f4, 0x00000003,
25990         0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
25991         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000,
25992         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
25993         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
25994         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000038, 0x00000040,
25995         0x0000000e, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x05000036,
25996         0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e,
25997     };
25998     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
25999 
26000     memset(&desc, 0, sizeof(desc));
26001     desc.rt_width = 640;
26002     desc.rt_height = 480;
26003     desc.rt_descriptor_count = 2;
26004     desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
26005     desc.no_pipeline = true;
26006     if (!init_test_context(&context, &desc))
26007         return;
26008     device = context.device;
26009     command_list = context.list;
26010     queue = context.queue;
26011 
26012     rtvs[0] = context.rtv;
26013     rtvs[1] = get_cpu_rtv_handle(&context, context.rtv_heap, 1);
26014     create_render_target(&context, &desc, &texture, &rtvs[1]);
26015 
26016     input_layout.pInputElementDescs = layout_desc;
26017     input_layout.NumElements = ARRAY_SIZE(layout_desc);
26018 
26019     init_pipeline_state_desc(&pso_desc, context.root_signature,
26020             context.render_target_desc.Format, &vs, &ps, &input_layout);
26021     pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
26022     pso_desc.GS = gs_5_0;
26023     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
26024             &IID_ID3D12PipelineState, (void **)&pso_5_0);
26025     ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
26026     pso_desc.GS = gs;
26027     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
26028             &IID_ID3D12PipelineState, (void **)&pso);
26029     ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
26030 
26031     vb = create_upload_buffer(context.device, sizeof(vertex), vertex);
26032     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
26033     vbv.StrideInBytes = sizeof(*vertex);
26034     vbv.SizeInBytes = sizeof(vertex);
26035 
26036     for (i = 0; i < ARRAY_SIZE(rtvs); ++i)
26037         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtvs[i], red, 0, NULL);
26038 
26039     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &rtvs[0], false, NULL);
26040     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
26041     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
26042     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
26043     ID3D12GraphicsCommandList_SetPipelineState(command_list, pso_5_0);
26044     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_POINTLIST);
26045     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
26046     ID3D12GraphicsCommandList_DrawInstanced(command_list, 1, 1, 0, 0);
26047 
26048     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &rtvs[1], false, NULL);
26049     ID3D12GraphicsCommandList_SetPipelineState(command_list, pso_5_0);
26050     ID3D12GraphicsCommandList_DrawInstanced(command_list, 1, 1, 0, 0);
26051 
26052     transition_resource_state(command_list, context.render_target,
26053             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
26054     transition_resource_state(command_list, texture,
26055             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
26056 
26057     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
26058     color = get_readback_uint(&rb, 320, 190, 0);
26059     ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
26060     color = get_readback_uint(&rb, 255, 240, 0);
26061     ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
26062     color = get_readback_uint(&rb, 320, 240, 0);
26063     ok(compare_color(color, 0xffffff00, 1), "Got unexpected color 0x%08x.\n", color);
26064     color = get_readback_uint(&rb, 385, 240, 0);
26065     ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
26066     color = get_readback_uint(&rb, 320, 290, 0);
26067     ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
26068     release_resource_readback(&rb);
26069 
26070     reset_command_list(command_list, context.allocator);
26071     get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list);
26072     color = get_readback_uint(&rb, 320, 190, 0);
26073     ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
26074     color = get_readback_uint(&rb, 255, 240, 0);
26075     ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
26076     color = get_readback_uint(&rb, 320, 240, 0);
26077     ok(compare_color(color, 0xffffff00, 1), "Got unexpected color 0x%08x.\n", color);
26078     color = get_readback_uint(&rb, 385, 240, 0);
26079     ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
26080     color = get_readback_uint(&rb, 320, 290, 0);
26081     ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
26082     release_resource_readback(&rb);
26083 
26084     ID3D12Resource_Release(vb);
26085     ID3D12Resource_Release(texture);
26086     ID3D12PipelineState_Release(pso);
26087     ID3D12PipelineState_Release(pso_5_0);
26088     destroy_test_context(&context);
26089 }
26090 
test_layered_rendering(void)26091 static void test_layered_rendering(void)
26092 {
26093     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
26094     ID3D12GraphicsCommandList *command_list;
26095     D3D12_INPUT_LAYOUT_DESC input_layout;
26096     struct test_context_desc desc;
26097     D3D12_VERTEX_BUFFER_VIEW vbv;
26098     struct test_context context;
26099     ID3D12CommandQueue *queue;
26100     ID3D12Device *device;
26101     ID3D12Resource *vb;
26102     HRESULT hr;
26103 
26104     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
26105     static const struct
26106     {
26107         uint32_t color;
26108         struct vec4 position;
26109         uint32_t layer;
26110     }
26111     vertices[] =
26112     {
26113         {0x00000000, {-1.0f, -1.0f, 0.0f, 1.0f}, 2},
26114         {0x00000000, {-1.0f,  1.0f, 0.0f, 1.0f}, 2},
26115         {0x00000000, { 1.0f, -1.0f, 0.0f, 1.0f}, 2},
26116         {0x00000000, { 1.0f,  1.0f, 0.0f, 1.0f}, 2},
26117         {0xff00ff00, {-1.0f, -1.0f, 0.0f, 1.0f}, 0},
26118         {0xff00ff00, {-1.0f,  1.0f, 0.0f, 1.0f}, 0},
26119         {0xff00ff00, { 1.0f, -1.0f, 0.0f, 1.0f}, 0},
26120         {0xff00ff00, { 1.0f,  1.0f, 0.0f, 1.0f}, 0},
26121         {0xffffff00, {-1.0f, -1.0f, 0.0f, 1.0f}, 3},
26122         {0xffffff00, {-1.0f,  1.0f, 0.0f, 1.0f}, 3},
26123         {0xffffff00, { 1.0f, -1.0f, 0.0f, 1.0f}, 3},
26124         {0xffffff00, { 1.0f,  1.0f, 0.0f, 1.0f}, 3},
26125     };
26126     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
26127     {
26128         {"COLOR",       0, DXGI_FORMAT_R8G8B8A8_UNORM,     0,  0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
26129         {"SV_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0,  4, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
26130         {"LAYER",       0, DXGI_FORMAT_R32_UINT,           0, 20, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
26131     };
26132     static const DWORD vs_code[] =
26133     {
26134 #if 0
26135         struct vertex
26136         {
26137             float4 color : COLOR;
26138             float4 position : SV_Position;
26139             uint layer : LAYER;
26140         };
26141 
26142         struct vertex main(in vertex v)
26143         {
26144             return v;
26145         }
26146 #endif
26147         0x43425844, 0x96d7f39a, 0x03d06cd5, 0x32c1fa04, 0xd509128f, 0x00000001, 0x000001ac, 0x00000003,
26148         0x0000002c, 0x0000009c, 0x0000010c, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
26149         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000056, 0x00000000, 0x00000000,
26150         0x00000003, 0x00000001, 0x00000f0f, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000002,
26151         0x00000101, 0x4f4c4f43, 0x56530052, 0x736f505f, 0x6f697469, 0x414c006e, 0x00524559, 0x4e47534f,
26152         0x00000068, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
26153         0x0000000f, 0x00000056, 0x00000000, 0x00000001, 0x00000003, 0x00000001, 0x0000000f, 0x00000062,
26154         0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000e01, 0x4f4c4f43, 0x56530052, 0x736f505f,
26155         0x6f697469, 0x414c006e, 0x00524559, 0x58454853, 0x00000098, 0x00010050, 0x00000026, 0x0100086a,
26156         0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x001010f2, 0x00000001, 0x0300005f, 0x00101012,
26157         0x00000002, 0x03000065, 0x001020f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000001, 0x00000001,
26158         0x03000065, 0x00102012, 0x00000002, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000,
26159         0x05000036, 0x001020f2, 0x00000001, 0x00101e46, 0x00000001, 0x05000036, 0x00102012, 0x00000002,
26160         0x0010100a, 0x00000002, 0x0100003e,
26161     };
26162     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
26163     static const DWORD gs_code[] =
26164     {
26165 #if 0
26166         struct gs_in
26167         {
26168             float4 color : COLOR;
26169             float4 position : SV_Position;
26170             uint layer : LAYER;
26171         };
26172 
26173         struct gs_out
26174         {
26175             float4 color : COLOR;
26176             float4 position : SV_Position;
26177             uint layer : SV_RenderTargetArrayIndex;
26178         };
26179 
26180         [maxvertexcount(3)]
26181         void main(triangle gs_in vin[3], inout TriangleStream<gs_out> vout)
26182         {
26183             gs_out o;
26184 
26185             o.color = vin[0].color;
26186             o.position = vin[0].position;
26187             o.layer = vin[0].layer;
26188             vout.Append(o);
26189 
26190             o.color = vin[1].color;
26191             o.position = vin[1].position;
26192             o.layer = vin[1].layer;
26193             vout.Append(o);
26194 
26195             o.color = vin[2].color;
26196             o.position = vin[2].position;
26197             o.layer = vin[2].layer;
26198             vout.Append(o);
26199         }
26200 #endif
26201         0x43425844, 0x29d7c0a0, 0xcf146fd1, 0x5cd36ca7, 0xab2b10ff, 0x00000001, 0x000002bc, 0x00000003,
26202         0x0000002c, 0x0000009c, 0x0000012c, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
26203         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000056, 0x00000000, 0x00000001,
26204         0x00000003, 0x00000001, 0x00000f0f, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000002,
26205         0x00000101, 0x4f4c4f43, 0x56530052, 0x736f505f, 0x6f697469, 0x414c006e, 0x00524559, 0x3547534f,
26206         0x00000088, 0x00000003, 0x00000008, 0x00000000, 0x0000005c, 0x00000000, 0x00000000, 0x00000003,
26207         0x00000000, 0x0000000f, 0x00000000, 0x00000062, 0x00000000, 0x00000001, 0x00000003, 0x00000001,
26208         0x0000000f, 0x00000000, 0x0000006e, 0x00000000, 0x00000004, 0x00000001, 0x00000002, 0x00000e01,
26209         0x4f4c4f43, 0x56530052, 0x736f505f, 0x6f697469, 0x5653006e, 0x6e65525f, 0x54726564, 0x65677261,
26210         0x72724174, 0x6e497961, 0x00786564, 0x58454853, 0x00000188, 0x00020050, 0x00000062, 0x0100086a,
26211         0x0400005f, 0x002010f2, 0x00000003, 0x00000000, 0x05000061, 0x002010f2, 0x00000003, 0x00000001,
26212         0x00000001, 0x0400005f, 0x00201012, 0x00000003, 0x00000002, 0x0100185d, 0x0300008f, 0x00110000,
26213         0x00000000, 0x0100285c, 0x03000065, 0x001020f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000001,
26214         0x00000001, 0x04000067, 0x00102012, 0x00000002, 0x00000004, 0x0200005e, 0x00000003, 0x06000036,
26215         0x001020f2, 0x00000000, 0x00201e46, 0x00000000, 0x00000000, 0x06000036, 0x001020f2, 0x00000001,
26216         0x00201e46, 0x00000000, 0x00000001, 0x06000036, 0x00102012, 0x00000002, 0x0020100a, 0x00000000,
26217         0x00000002, 0x03000075, 0x00110000, 0x00000000, 0x06000036, 0x001020f2, 0x00000000, 0x00201e46,
26218         0x00000001, 0x00000000, 0x06000036, 0x001020f2, 0x00000001, 0x00201e46, 0x00000001, 0x00000001,
26219         0x06000036, 0x00102012, 0x00000002, 0x0020100a, 0x00000001, 0x00000002, 0x03000075, 0x00110000,
26220         0x00000000, 0x06000036, 0x001020f2, 0x00000000, 0x00201e46, 0x00000002, 0x00000000, 0x06000036,
26221         0x001020f2, 0x00000001, 0x00201e46, 0x00000002, 0x00000001, 0x06000036, 0x00102012, 0x00000002,
26222         0x0020100a, 0x00000002, 0x00000002, 0x03000075, 0x00110000, 0x00000000, 0x0100003e,
26223     };
26224     static const D3D12_SHADER_BYTECODE gs = {gs_code, sizeof(gs_code)};
26225     static const DWORD ps_code[] =
26226     {
26227 #if 0
26228         float4 main(float4 color : COLOR) : SV_Target0
26229         {
26230             return color;
26231         }
26232 #endif
26233         0x43425844, 0xdccf00bf, 0xcc96375e, 0xba21f157, 0xe47b8b1c, 0x00000001, 0x000000d4, 0x00000003,
26234         0x0000002c, 0x0000005c, 0x00000090, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
26235         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
26236         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
26237         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000003c, 0x00000050, 0x0000000f,
26238         0x0100086a, 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036,
26239         0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
26240     };
26241     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
26242 
26243     memset(&desc, 0, sizeof(desc));
26244     desc.rt_array_size = 4;
26245     desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
26246     desc.no_pipeline = true;
26247     if (!init_test_context(&context, &desc))
26248         return;
26249     device = context.device;
26250     command_list = context.list;
26251     queue = context.queue;
26252 
26253     input_layout.pInputElementDescs = layout_desc;
26254     input_layout.NumElements = ARRAY_SIZE(layout_desc);
26255 
26256     init_pipeline_state_desc(&pso_desc, context.root_signature,
26257             context.render_target_desc.Format, &vs, &ps, &input_layout);
26258     pso_desc.GS = gs;
26259     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
26260             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
26261     ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
26262 
26263     vb = create_upload_buffer(context.device, sizeof(vertices), vertices);
26264     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
26265     vbv.StrideInBytes = sizeof(*vertices);
26266     vbv.SizeInBytes = sizeof(vertices);
26267 
26268     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
26269 
26270     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
26271     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
26272     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
26273     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
26274     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
26275     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
26276     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
26277     ID3D12GraphicsCommandList_DrawInstanced(command_list, 12, 1, 0, 0);
26278 
26279     transition_resource_state(command_list, context.render_target,
26280             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
26281 
26282     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
26283     reset_command_list(command_list, context.allocator);
26284     check_sub_resource_uint(context.render_target, 1, queue, command_list, 0xffffffff, 0);
26285     reset_command_list(command_list, context.allocator);
26286     check_sub_resource_uint(context.render_target, 2, queue, command_list, 0x00000000, 0);
26287     reset_command_list(command_list, context.allocator);
26288     check_sub_resource_uint(context.render_target, 3, queue, command_list, 0xffffff00, 0);
26289 
26290     ID3D12Resource_Release(vb);
26291     destroy_test_context(&context);
26292 }
26293 
test_ps_layer(void)26294 static void test_ps_layer(void)
26295 {
26296     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
26297     ID3D12GraphicsCommandList *command_list;
26298     struct test_context_desc desc;
26299     struct test_context context;
26300     ID3D12CommandQueue *queue;
26301     ID3D12Device *device;
26302     unsigned int i;
26303     HRESULT hr;
26304 
26305     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
26306     static const DWORD vs_code[] =
26307     {
26308 #if 0
26309         void main(in uint vertex_id : SV_VertexID, out uint layer : LAYER)
26310         {
26311             layer = vertex_id;
26312         }
26313 #endif
26314         0x43425844, 0xd2b4abd8, 0xf9adf7df, 0xed1b4eb0, 0x4bf54391, 0x00000001, 0x000000d8, 0x00000003,
26315         0x0000002c, 0x00000060, 0x00000090, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
26316         0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000101, 0x565f5653, 0x65747265, 0x00444978,
26317         0x4e47534f, 0x00000028, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001,
26318         0x00000000, 0x00000e01, 0x4559414c, 0xabab0052, 0x58454853, 0x00000040, 0x00010050, 0x00000010,
26319         0x0100086a, 0x04000060, 0x00101012, 0x00000000, 0x00000006, 0x03000065, 0x00102012, 0x00000000,
26320         0x05000036, 0x00102012, 0x00000000, 0x0010100a, 0x00000000, 0x0100003e,
26321     };
26322     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
26323     static const DWORD gs_code[] =
26324     {
26325 #if 0
26326         struct gs_in
26327         {
26328             uint layer : LAYER;
26329         };
26330 
26331         struct gs_out
26332         {
26333             float4 position : SV_Position;
26334             uint layer : SV_RenderTargetArrayIndex;
26335         };
26336 
26337         [maxvertexcount(3)]
26338         void main(point gs_in vin[1], inout TriangleStream<gs_out> vout)
26339         {
26340             gs_out o;
26341 
26342             o.layer = vin[0].layer;
26343 
26344             o.position = float4(-1, 1, 0, 1);
26345             vout.Append(o);
26346 
26347             o.position = float4(3, 1, 0, 1);
26348             vout.Append(o);
26349 
26350             o.position = float4(-1, -3, 0, 1);
26351             vout.Append(o);
26352         }
26353 #endif
26354         0x43425844, 0x2589d822, 0x7557587c, 0x7d7e9cc0, 0x6bad86aa, 0x00000001, 0x000001fc, 0x00000003,
26355         0x0000002c, 0x0000005c, 0x000000cc, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
26356         0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000101, 0x4559414c, 0xabab0052, 0x3547534f,
26357         0x00000068, 0x00000002, 0x00000008, 0x00000000, 0x00000040, 0x00000000, 0x00000001, 0x00000003,
26358         0x00000000, 0x0000000f, 0x00000000, 0x0000004c, 0x00000000, 0x00000004, 0x00000001, 0x00000001,
26359         0x00000e01, 0x505f5653, 0x7469736f, 0x006e6f69, 0x525f5653, 0x65646e65, 0x72615472, 0x41746567,
26360         0x79617272, 0x65646e49, 0xabab0078, 0x58454853, 0x00000128, 0x00020050, 0x0000004a, 0x0100086a,
26361         0x0400005f, 0x00201012, 0x00000001, 0x00000000, 0x0100085d, 0x0300008f, 0x00110000, 0x00000000,
26362         0x0100285c, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x04000067, 0x00102012, 0x00000001,
26363         0x00000004, 0x0200005e, 0x00000003, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0xbf800000,
26364         0x3f800000, 0x00000000, 0x3f800000, 0x06000036, 0x00102012, 0x00000001, 0x0020100a, 0x00000000,
26365         0x00000000, 0x03000075, 0x00110000, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002,
26366         0x40400000, 0x3f800000, 0x00000000, 0x3f800000, 0x06000036, 0x00102012, 0x00000001, 0x0020100a,
26367         0x00000000, 0x00000000, 0x03000075, 0x00110000, 0x00000000, 0x08000036, 0x001020f2, 0x00000000,
26368         0x00004002, 0xbf800000, 0xc0400000, 0x00000000, 0x3f800000, 0x06000036, 0x00102012, 0x00000001,
26369         0x0020100a, 0x00000000, 0x00000000, 0x03000075, 0x00110000, 0x00000000, 0x0100003e,
26370     };
26371     static const D3D12_SHADER_BYTECODE gs = {gs_code, sizeof(gs_code)};
26372     static const DWORD ps_code[] =
26373     {
26374 #if 0
26375         float4 main(float4 p : SV_Position, uint layer : SV_RenderTargetArrayIndex) : SV_Target0
26376         {
26377             return layer / 255.0;
26378         }
26379 #endif
26380         0x43425844, 0x53474926, 0xbd247b84, 0x389660f4, 0x331cf598, 0x00000001, 0x00000140, 0x00000003,
26381         0x0000002c, 0x00000094, 0x000000c8, 0x4e475349, 0x00000060, 0x00000002, 0x00000008, 0x00000038,
26382         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000004,
26383         0x00000001, 0x00000001, 0x00000101, 0x505f5653, 0x7469736f, 0x006e6f69, 0x525f5653, 0x65646e65,
26384         0x72615472, 0x41746567, 0x79617272, 0x65646e49, 0xabab0078, 0x4e47534f, 0x0000002c, 0x00000001,
26385         0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653,
26386         0x65677261, 0xabab0074, 0x58454853, 0x00000070, 0x00000050, 0x0000001c, 0x0100086a, 0x04000864,
26387         0x00101012, 0x00000001, 0x00000004, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001,
26388         0x05000056, 0x00100012, 0x00000000, 0x0010100a, 0x00000001, 0x0a000038, 0x001020f2, 0x00000000,
26389         0x00100006, 0x00000000, 0x00004002, 0x3b808081, 0x3b808081, 0x3b808081, 0x3b808081, 0x0100003e,
26390     };
26391     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
26392     static const unsigned int expected_results[] =
26393     {
26394         0x00000000,
26395         0x01010101,
26396         0x02020202,
26397         0x03030303,
26398         0x04040404,
26399         0x05050505,
26400     };
26401 
26402     memset(&desc, 0, sizeof(desc));
26403     desc.rt_array_size = 6;
26404     desc.no_pipeline = true;
26405     if (!init_test_context(&context, &desc))
26406         return;
26407     device = context.device;
26408     command_list = context.list;
26409     queue = context.queue;
26410 
26411     init_pipeline_state_desc(&pso_desc, context.root_signature,
26412             context.render_target_desc.Format, &vs, &ps, NULL);
26413     pso_desc.GS = gs;
26414     pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
26415     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
26416             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
26417     ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
26418 
26419     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
26420 
26421     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
26422     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
26423     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
26424     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
26425     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
26426     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_POINTLIST);
26427     ID3D12GraphicsCommandList_DrawInstanced(command_list, 6, 1, 0, 0);
26428 
26429     transition_resource_state(command_list, context.render_target,
26430             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
26431 
26432     for (i = 0; i < ARRAY_SIZE(expected_results); ++i)
26433     {
26434         check_sub_resource_uint(context.render_target, i, queue, command_list, expected_results[i], 0);
26435         reset_command_list(command_list, context.allocator);
26436     }
26437 
26438     destroy_test_context(&context);
26439 }
26440 
test_nop_tessellation_shaders(void)26441 static void test_nop_tessellation_shaders(void)
26442 {
26443     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
26444     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
26445     ID3D12GraphicsCommandList *command_list;
26446     struct test_context_desc desc;
26447     struct test_context context;
26448     ID3D12CommandQueue *queue;
26449     struct vec4 tess_factors;
26450     unsigned int i;
26451     HRESULT hr;
26452 
26453     static const DWORD hs_cb_code[] =
26454     {
26455 #if 0
26456         float4 tess_factor;
26457 
26458         struct data
26459         {
26460             float4 position : SV_Position;
26461         };
26462 
26463         struct patch_constant_data
26464         {
26465             float edges[3] : SV_TessFactor;
26466             float inside : SV_InsideTessFactor;
26467         };
26468 
26469         void patch_constant(InputPatch<data, 3> input, out patch_constant_data output)
26470         {
26471             output.edges[0] = tess_factor.x;
26472             output.edges[1] = tess_factor.y;
26473             output.edges[2] = tess_factor.z;
26474             output.inside = tess_factor.w;
26475         }
26476 
26477         [domain("tri")]
26478         [outputcontrolpoints(3)]
26479         [partitioning("integer")]
26480         [outputtopology("triangle_cw")]
26481         [patchconstantfunc("patch_constant")]
26482         data hs_main(InputPatch<data, 3> input, uint i : SV_OutputControlPointID)
26483         {
26484             return input[i];
26485         }
26486 #endif
26487         0x43425844, 0x7e698b53, 0x830de202, 0x4287601f, 0x4315faa4, 0x00000001, 0x00000228, 0x00000004,
26488         0x00000030, 0x00000064, 0x00000098, 0x0000012c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008,
26489         0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x505f5653, 0x7469736f,
26490         0x006e6f69, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001,
26491         0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x47534350, 0x0000008c,
26492         0x00000004, 0x00000008, 0x00000068, 0x00000000, 0x0000000d, 0x00000003, 0x00000000, 0x00000e01,
26493         0x00000068, 0x00000001, 0x0000000d, 0x00000003, 0x00000001, 0x00000e01, 0x00000068, 0x00000002,
26494         0x0000000d, 0x00000003, 0x00000002, 0x00000e01, 0x00000076, 0x00000000, 0x0000000e, 0x00000003,
26495         0x00000003, 0x00000e01, 0x545f5653, 0x46737365, 0x6f746361, 0x56530072, 0x736e495f, 0x54656469,
26496         0x46737365, 0x6f746361, 0xabab0072, 0x58454853, 0x000000f4, 0x00030050, 0x0000003d, 0x01000071,
26497         0x01001893, 0x01001894, 0x01001095, 0x01000896, 0x01001897, 0x0100086a, 0x04000059, 0x00208e46,
26498         0x00000000, 0x00000001, 0x01000073, 0x04000067, 0x00102012, 0x00000000, 0x00000011, 0x06000036,
26499         0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0100003e, 0x01000073, 0x04000067,
26500         0x00102012, 0x00000001, 0x00000012, 0x06000036, 0x00102012, 0x00000001, 0x0020801a, 0x00000000,
26501         0x00000000, 0x0100003e, 0x01000073, 0x04000067, 0x00102012, 0x00000002, 0x00000013, 0x06000036,
26502         0x00102012, 0x00000002, 0x0020802a, 0x00000000, 0x00000000, 0x0100003e, 0x01000073, 0x04000067,
26503         0x00102012, 0x00000003, 0x00000014, 0x06000036, 0x00102012, 0x00000003, 0x0020803a, 0x00000000,
26504         0x00000000, 0x0100003e,
26505     };
26506     static const D3D12_SHADER_BYTECODE hs_cb = {hs_cb_code, sizeof(hs_cb_code)};
26507 #if 0
26508     struct data
26509     {
26510         float4 position : SV_Position;
26511     };
26512 
26513     struct patch_constant_data
26514     {
26515         float edges[3] : SV_TessFactor;
26516         float inside : SV_InsideTessFactor;
26517     };
26518 
26519     void patch_constant(InputPatch<data, 3> input, out patch_constant_data output)
26520     {
26521         output.edges[0] = output.edges[1] = output.edges[2] = 1.0f;
26522         output.inside = 1.0f;
26523     }
26524 
26525     [domain("tri")]
26526     [outputcontrolpoints(3)]
26527     [partitioning("integer")]
26528     [outputtopology("triangle_cw")]
26529     [patchconstantfunc("patch_constant")]
26530     data hs_main(InputPatch<data, 3> input, uint i : SV_OutputControlPointID)
26531     {
26532         return input[i];
26533     }
26534 
26535     [domain("tri")]
26536     void ds_main(patch_constant_data input,
26537             float3 tess_coord : SV_DomainLocation,
26538             const OutputPatch<data, 3> patch,
26539             out data output)
26540     {
26541         output.position = tess_coord.x * patch[0].position
26542                 + tess_coord.y * patch[1].position
26543                 + tess_coord.z * patch[2].position;
26544     }
26545 #endif
26546     static const DWORD hs_code[] =
26547     {
26548         0x43425844, 0x0e9a8861, 0x39351e76, 0x0e10883f, 0x6054b5a1, 0x00000001, 0x0000020c, 0x00000004,
26549         0x00000030, 0x00000064, 0x00000098, 0x0000012c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008,
26550         0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x505f5653, 0x7469736f,
26551         0x006e6f69, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001,
26552         0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x47534350, 0x0000008c,
26553         0x00000004, 0x00000008, 0x00000068, 0x00000000, 0x0000000d, 0x00000003, 0x00000000, 0x00000e01,
26554         0x00000068, 0x00000001, 0x0000000d, 0x00000003, 0x00000001, 0x00000e01, 0x00000068, 0x00000002,
26555         0x0000000d, 0x00000003, 0x00000002, 0x00000e01, 0x00000076, 0x00000000, 0x0000000e, 0x00000003,
26556         0x00000003, 0x00000e01, 0x545f5653, 0x46737365, 0x6f746361, 0x56530072, 0x736e495f, 0x54656469,
26557         0x46737365, 0x6f746361, 0xabab0072, 0x58454853, 0x000000d8, 0x00030050, 0x00000036, 0x01000071,
26558         0x01001893, 0x01001894, 0x01001095, 0x01000896, 0x01001897, 0x0100086a, 0x01000073, 0x02000099,
26559         0x00000003, 0x0200005f, 0x00017000, 0x04000067, 0x00102012, 0x00000000, 0x00000011, 0x04000067,
26560         0x00102012, 0x00000001, 0x00000012, 0x04000067, 0x00102012, 0x00000002, 0x00000013, 0x02000068,
26561         0x00000001, 0x0400005b, 0x00102012, 0x00000000, 0x00000003, 0x04000036, 0x00100012, 0x00000000,
26562         0x0001700a, 0x06000036, 0x00902012, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0100003e,
26563         0x01000073, 0x04000067, 0x00102012, 0x00000003, 0x00000014, 0x05000036, 0x00102012, 0x00000003,
26564         0x00004001, 0x3f800000, 0x0100003e,
26565     };
26566     static const D3D12_SHADER_BYTECODE hs = {hs_code, sizeof(hs_code)};
26567     static const DWORD ds_code[] =
26568     {
26569         0x43425844, 0x8ed11021, 0x414dff74, 0x426849eb, 0x312f4860, 0x00000001, 0x000001e0, 0x00000004,
26570         0x00000030, 0x00000064, 0x000000f8, 0x0000012c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008,
26571         0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x505f5653, 0x7469736f,
26572         0x006e6f69, 0x47534350, 0x0000008c, 0x00000004, 0x00000008, 0x00000068, 0x00000000, 0x0000000d,
26573         0x00000003, 0x00000000, 0x00000001, 0x00000068, 0x00000001, 0x0000000d, 0x00000003, 0x00000001,
26574         0x00000001, 0x00000068, 0x00000002, 0x0000000d, 0x00000003, 0x00000002, 0x00000001, 0x00000076,
26575         0x00000000, 0x0000000e, 0x00000003, 0x00000003, 0x00000001, 0x545f5653, 0x46737365, 0x6f746361,
26576         0x56530072, 0x736e495f, 0x54656469, 0x46737365, 0x6f746361, 0xabab0072, 0x4e47534f, 0x0000002c,
26577         0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f,
26578         0x505f5653, 0x7469736f, 0x006e6f69, 0x58454853, 0x000000ac, 0x00040050, 0x0000002b, 0x01001893,
26579         0x01001095, 0x0100086a, 0x0200005f, 0x0001c072, 0x0400005f, 0x002190f2, 0x00000003, 0x00000000,
26580         0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x02000068, 0x00000001, 0x07000038, 0x001000f2,
26581         0x00000000, 0x0001c556, 0x00219e46, 0x00000001, 0x00000000, 0x09000032, 0x001000f2, 0x00000000,
26582         0x0001c006, 0x00219e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000, 0x09000032, 0x001020f2,
26583         0x00000000, 0x0001caa6, 0x00219e46, 0x00000002, 0x00000000, 0x00100e46, 0x00000000, 0x0100003e,
26584     };
26585     static const D3D12_SHADER_BYTECODE ds = {ds_code, sizeof(ds_code)};
26586     static const DWORD hs_index_range_code[] =
26587     {
26588 #if 0
26589         float4 tess_factor;
26590 
26591         struct data
26592         {
26593             float4 position : SV_Position;
26594         };
26595 
26596         struct patch_constant_data
26597         {
26598             float edges[3] : SV_TessFactor;
26599             float inside : SV_InsideTessFactor;
26600         };
26601 
26602         void patch_constant(InputPatch<data, 3> input, out patch_constant_data output)
26603         {
26604             output.edges[0] = tess_factor.x;
26605             output.edges[1] = 1.0f;
26606             output.edges[2] = 1.0f;
26607             output.inside = tess_factor.y;
26608         }
26609 
26610         [domain("tri")]
26611         [outputcontrolpoints(3)]
26612         [partitioning("integer")]
26613         [outputtopology("triangle_cw")]
26614         [patchconstantfunc("patch_constant")]
26615         data hs_main(InputPatch<data, 3> input, uint i : SV_OutputControlPointID)
26616         {
26617             return input[i];
26618         }
26619 #endif
26620         0x43425844, 0xf9d52cfc, 0xb299036a, 0x66bf56b7, 0x6161e921, 0x00000001, 0x00000244, 0x00000004,
26621         0x00000030, 0x00000064, 0x00000098, 0x0000012c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008,
26622         0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x505f5653, 0x7469736f,
26623         0x006e6f69, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001,
26624         0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x47534350, 0x0000008c,
26625         0x00000004, 0x00000008, 0x00000068, 0x00000000, 0x0000000d, 0x00000003, 0x00000000, 0x00000e01,
26626         0x00000068, 0x00000001, 0x0000000d, 0x00000003, 0x00000001, 0x00000e01, 0x00000068, 0x00000002,
26627         0x0000000d, 0x00000003, 0x00000002, 0x00000e01, 0x00000076, 0x00000000, 0x0000000e, 0x00000003,
26628         0x00000003, 0x00000e01, 0x545f5653, 0x46737365, 0x6f746361, 0x56530072, 0x736e495f, 0x54656469,
26629         0x46737365, 0x6f746361, 0xabab0072, 0x58454853, 0x00000110, 0x00030050, 0x00000044, 0x01000071,
26630         0x01001893, 0x01001894, 0x01001095, 0x01000896, 0x01001897, 0x0100086a, 0x04000059, 0x00208e46,
26631         0x00000000, 0x00000001, 0x01000073, 0x04000067, 0x00102012, 0x00000000, 0x00000011, 0x06000036,
26632         0x00102012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0100003e, 0x01000073, 0x02000099,
26633         0x00000002, 0x0200005f, 0x00017000, 0x04000067, 0x00102012, 0x00000001, 0x00000012, 0x04000067,
26634         0x00102012, 0x00000002, 0x00000013, 0x02000068, 0x00000001, 0x0400005b, 0x00102012, 0x00000001,
26635         0x00000002, 0x04000036, 0x00100012, 0x00000000, 0x0001700a, 0x07000036, 0x00d02012, 0x00000001,
26636         0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0100003e, 0x01000073, 0x04000067, 0x00102012,
26637         0x00000003, 0x00000014, 0x06000036, 0x00102012, 0x00000003, 0x0020801a, 0x00000000, 0x00000000,
26638         0x0100003e,
26639     };
26640     static const D3D12_SHADER_BYTECODE hs_index_range = {hs_index_range_code, sizeof(hs_index_range_code)};
26641     static const D3D12_SHADER_BYTECODE *hull_shaders[] = {&hs_cb, &hs, &hs_index_range};
26642 
26643     memset(&desc, 0, sizeof(desc));
26644     desc.no_root_signature = true;
26645     if (!init_test_context(&context, &desc))
26646         return;
26647     command_list = context.list;
26648     queue = context.queue;
26649 
26650     context.root_signature = create_32bit_constants_root_signature(context.device,
26651             0, 4, D3D12_SHADER_VISIBILITY_HULL);
26652 
26653     init_pipeline_state_desc(&pso_desc, context.root_signature,
26654             context.render_target_desc.Format, NULL, NULL, NULL);
26655     pso_desc.HS = hs_cb;
26656     pso_desc.DS = ds;
26657     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
26658             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
26659     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
26660     pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
26661     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
26662             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
26663     ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
26664     ID3D12PipelineState_Release(context.pipeline_state);
26665 
26666     for (i = 0; i < ARRAY_SIZE(hull_shaders); ++i)
26667     {
26668         vkd3d_test_set_context("Test %u", i);
26669 
26670         pso_desc.HS = *hull_shaders[i];
26671         hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
26672                 &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
26673         ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
26674 
26675         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
26676 
26677         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
26678         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
26679         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
26680         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST);
26681         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
26682         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
26683         tess_factors.x = tess_factors.y = tess_factors.z = tess_factors.w = 1.0f;
26684         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 4, &tess_factors.x, 0);
26685         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
26686 
26687         transition_resource_state(command_list, context.render_target,
26688                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
26689 
26690         check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
26691 
26692         reset_command_list(command_list, context.allocator);
26693         transition_resource_state(command_list, context.render_target,
26694                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
26695 
26696         ID3D12PipelineState_Release(context.pipeline_state);
26697         context.pipeline_state = NULL;
26698     }
26699     vkd3d_test_set_context(NULL);
26700 
26701     destroy_test_context(&context);
26702 }
26703 
26704 struct triangle
26705 {
26706     struct vec4 v[3];
26707 };
26708 
26709 #define check_triangles(a, b, c, d, e) check_triangles_(__LINE__, a, b, c, d, e)
check_triangles_(unsigned int line,ID3D12Resource * buffer,ID3D12CommandQueue * queue,ID3D12GraphicsCommandList * command_list,const struct triangle * triangles,unsigned int triangle_count)26710 static void check_triangles_(unsigned int line, ID3D12Resource *buffer,
26711         ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list,
26712         const struct triangle *triangles, unsigned int triangle_count)
26713 {
26714     const struct triangle *current, *expected;
26715     struct resource_readback rb;
26716     unsigned int i, j, offset;
26717     bool all_match = true;
26718 
26719     get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
26720 
26721     for (i = 0; i < triangle_count; ++i)
26722     {
26723         current = get_readback_data(&rb, i, 0, 0, sizeof(*current));
26724         expected = &triangles[i];
26725 
26726         offset = ~0u;
26727         for (j = 0; j < ARRAY_SIZE(expected->v); ++j)
26728         {
26729             if (compare_vec4(&current->v[0], &expected->v[j], 0))
26730             {
26731                 offset = j;
26732                 break;
26733             }
26734         }
26735 
26736         if (offset == ~0u)
26737         {
26738             all_match = false;
26739             break;
26740         }
26741 
26742         for (j = 0; j < ARRAY_SIZE(expected->v); ++j)
26743         {
26744             if (!compare_vec4(&current->v[j], &expected->v[(j + offset) % 3], 0))
26745             {
26746                 all_match = false;
26747                 break;
26748             }
26749         }
26750         if (!all_match)
26751             break;
26752     }
26753 
26754     ok_(line)(all_match, "Triangle %u vertices {%.8e, %.8e, %.8e, %.8e}, "
26755             "{%.8e, %.8e, %.8e, %.8e}, {%.8e, %.8e, %.8e, %.8e} "
26756             "do not match {%.8e, %.8e, %.8e, %.8e}, {%.8e, %.8e, %.8e, %.8e}, "
26757             "{%.8e, %.8e, %.8e, %.8e}.\n", i,
26758             current->v[0].x, current->v[0].y, current->v[0].z, current->v[0].w,
26759             current->v[1].x, current->v[1].y, current->v[1].z, current->v[1].w,
26760             current->v[2].x, current->v[2].y, current->v[2].z, current->v[2].w,
26761             expected->v[0].x, expected->v[0].y, expected->v[0].z, expected->v[0].w,
26762             expected->v[1].x, expected->v[1].y, expected->v[1].z, expected->v[1].w,
26763             expected->v[2].x, expected->v[2].y, expected->v[2].z, expected->v[2].w);
26764 
26765     release_resource_readback(&rb);
26766 }
26767 
test_quad_tessellation(void)26768 static void test_quad_tessellation(void)
26769 {
26770     static const DWORD vs_code[] =
26771     {
26772 #if 0
26773         void main(float4 in_position : POSITION, out float4 out_position : SV_POSITION)
26774         {
26775             out_position = in_position;
26776         }
26777 #endif
26778         0x43425844, 0xa7a2f22d, 0x83ff2560, 0xe61638bd, 0x87e3ce90, 0x00000001, 0x000000d8, 0x00000003,
26779         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
26780         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
26781         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
26782         0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040,
26783         0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
26784         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
26785     };
26786     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
26787 #if 0
26788     struct point_data
26789     {
26790         float4 position : SV_POSITION;
26791     };
26792 
26793     struct patch_constant_data
26794     {
26795         float edges[4] : SV_TessFactor;
26796         float inside[2] : SV_InsideTessFactor;
26797     };
26798 
26799     float4 tess_factors;
26800     float2 inside_tess_factors;
26801 
26802     patch_constant_data patch_constant(InputPatch<point_data, 4> input)
26803     {
26804         patch_constant_data output;
26805 
26806         output.edges[0] = tess_factors.x;
26807         output.edges[1] = tess_factors.y;
26808         output.edges[2] = tess_factors.z;
26809         output.edges[3] = tess_factors.w;
26810         output.inside[0] = inside_tess_factors.x;
26811         output.inside[1] = inside_tess_factors.y;
26812 
26813         return output;
26814     }
26815 
26816     [domain("quad")]
26817     [outputcontrolpoints(4)]
26818     [outputtopology("triangle_ccw")]
26819     [partitioning("integer")]
26820     [patchconstantfunc("patch_constant")]
26821     point_data hs_main(InputPatch<point_data, 4> input,
26822             uint i : SV_OutputControlPointID)
26823     {
26824         return input[i];
26825     }
26826 
26827     [domain("quad")]
26828     point_data ds_main(patch_constant_data input,
26829             float2 tess_coord : SV_DomainLocation,
26830             const OutputPatch<point_data, 4> patch)
26831     {
26832         point_data output;
26833 
26834         float4 a = lerp(patch[0].position, patch[1].position, tess_coord.x);
26835         float4 b = lerp(patch[2].position, patch[3].position, tess_coord.x);
26836         output.position = lerp(a, b, tess_coord.y);
26837 
26838         return output;
26839     }
26840 #endif
26841     static const DWORD hs_quad_ccw_code[] =
26842     {
26843         0x43425844, 0xdf8df700, 0x58b08fb1, 0xbd23d2c3, 0xcf884094, 0x00000001, 0x000002b8, 0x00000004,
26844         0x00000030, 0x00000064, 0x00000098, 0x0000015c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008,
26845         0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x505f5653, 0x5449534f,
26846         0x004e4f49, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
26847         0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x47534350, 0x000000bc,
26848         0x00000006, 0x00000008, 0x00000098, 0x00000000, 0x0000000b, 0x00000003, 0x00000000, 0x00000e01,
26849         0x00000098, 0x00000001, 0x0000000b, 0x00000003, 0x00000001, 0x00000e01, 0x00000098, 0x00000002,
26850         0x0000000b, 0x00000003, 0x00000002, 0x00000e01, 0x00000098, 0x00000003, 0x0000000b, 0x00000003,
26851         0x00000003, 0x00000e01, 0x000000a6, 0x00000000, 0x0000000c, 0x00000003, 0x00000004, 0x00000e01,
26852         0x000000a6, 0x00000001, 0x0000000c, 0x00000003, 0x00000005, 0x00000e01, 0x545f5653, 0x46737365,
26853         0x6f746361, 0x56530072, 0x736e495f, 0x54656469, 0x46737365, 0x6f746361, 0xabab0072, 0x58454853,
26854         0x00000154, 0x00030050, 0x00000055, 0x01000071, 0x01002093, 0x01002094, 0x01001895, 0x01000896,
26855         0x01002097, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x01000073, 0x04000067,
26856         0x00102012, 0x00000000, 0x0000000b, 0x06000036, 0x00102012, 0x00000000, 0x0020800a, 0x00000000,
26857         0x00000000, 0x0100003e, 0x01000073, 0x04000067, 0x00102012, 0x00000001, 0x0000000c, 0x06000036,
26858         0x00102012, 0x00000001, 0x0020801a, 0x00000000, 0x00000000, 0x0100003e, 0x01000073, 0x04000067,
26859         0x00102012, 0x00000002, 0x0000000d, 0x06000036, 0x00102012, 0x00000002, 0x0020802a, 0x00000000,
26860         0x00000000, 0x0100003e, 0x01000073, 0x04000067, 0x00102012, 0x00000003, 0x0000000e, 0x06000036,
26861         0x00102012, 0x00000003, 0x0020803a, 0x00000000, 0x00000000, 0x0100003e, 0x01000073, 0x04000067,
26862         0x00102012, 0x00000004, 0x0000000f, 0x06000036, 0x00102012, 0x00000004, 0x0020800a, 0x00000000,
26863         0x00000001, 0x0100003e, 0x01000073, 0x04000067, 0x00102012, 0x00000005, 0x00000010, 0x06000036,
26864         0x00102012, 0x00000005, 0x0020801a, 0x00000000, 0x00000001, 0x0100003e,
26865     };
26866     static const D3D12_SHADER_BYTECODE hs_quad_ccw = {hs_quad_ccw_code, sizeof(hs_quad_ccw_code)};
26867     static const DWORD ds_code[] =
26868     {
26869         0x43425844, 0xeb6b7631, 0x07f5469e, 0xed0cbf4a, 0x7158b3a6, 0x00000001, 0x00000284, 0x00000004,
26870         0x00000030, 0x00000064, 0x00000128, 0x0000015c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008,
26871         0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x505f5653, 0x5449534f,
26872         0x004e4f49, 0x47534350, 0x000000bc, 0x00000006, 0x00000008, 0x00000098, 0x00000000, 0x0000000b,
26873         0x00000003, 0x00000000, 0x00000001, 0x00000098, 0x00000001, 0x0000000b, 0x00000003, 0x00000001,
26874         0x00000001, 0x00000098, 0x00000002, 0x0000000b, 0x00000003, 0x00000002, 0x00000001, 0x00000098,
26875         0x00000003, 0x0000000b, 0x00000003, 0x00000003, 0x00000001, 0x000000a6, 0x00000000, 0x0000000c,
26876         0x00000003, 0x00000004, 0x00000001, 0x000000a6, 0x00000001, 0x0000000c, 0x00000003, 0x00000005,
26877         0x00000001, 0x545f5653, 0x46737365, 0x6f746361, 0x56530072, 0x736e495f, 0x54656469, 0x46737365,
26878         0x6f746361, 0xabab0072, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000,
26879         0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x58454853,
26880         0x00000120, 0x00040050, 0x00000048, 0x01002093, 0x01001895, 0x0100086a, 0x0200005f, 0x0001c032,
26881         0x0400005f, 0x002190f2, 0x00000004, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
26882         0x02000068, 0x00000002, 0x0a000000, 0x001000f2, 0x00000000, 0x80219e46, 0x00000041, 0x00000002,
26883         0x00000000, 0x00219e46, 0x00000003, 0x00000000, 0x09000032, 0x001000f2, 0x00000000, 0x0001c006,
26884         0x00100e46, 0x00000000, 0x00219e46, 0x00000002, 0x00000000, 0x0a000000, 0x001000f2, 0x00000001,
26885         0x80219e46, 0x00000041, 0x00000000, 0x00000000, 0x00219e46, 0x00000001, 0x00000000, 0x09000032,
26886         0x001000f2, 0x00000001, 0x0001c006, 0x00100e46, 0x00000001, 0x00219e46, 0x00000000, 0x00000000,
26887         0x08000000, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x80100e46, 0x00000041, 0x00000001,
26888         0x08000032, 0x001020f2, 0x00000000, 0x0001c556, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001,
26889         0x0100003e,
26890     };
26891     static const D3D12_SHADER_BYTECODE ds = {ds_code, sizeof(ds_code)};
26892 #if 0
26893     ...
26894     [outputtopology("triangle_cw")]
26895     ...
26896 #endif
26897     static const DWORD hs_quad_cw_code[] =
26898     {
26899         0x43425844, 0x1ab30cc8, 0x94174771, 0x61f4cdd0, 0xa287f62c, 0x00000001, 0x000002b8, 0x00000004,
26900         0x00000030, 0x00000064, 0x00000098, 0x0000015c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008,
26901         0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x505f5653, 0x5449534f,
26902         0x004e4f49, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
26903         0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x47534350, 0x000000bc,
26904         0x00000006, 0x00000008, 0x00000098, 0x00000000, 0x0000000b, 0x00000003, 0x00000000, 0x00000e01,
26905         0x00000098, 0x00000001, 0x0000000b, 0x00000003, 0x00000001, 0x00000e01, 0x00000098, 0x00000002,
26906         0x0000000b, 0x00000003, 0x00000002, 0x00000e01, 0x00000098, 0x00000003, 0x0000000b, 0x00000003,
26907         0x00000003, 0x00000e01, 0x000000a6, 0x00000000, 0x0000000c, 0x00000003, 0x00000004, 0x00000e01,
26908         0x000000a6, 0x00000001, 0x0000000c, 0x00000003, 0x00000005, 0x00000e01, 0x545f5653, 0x46737365,
26909         0x6f746361, 0x56530072, 0x736e495f, 0x54656469, 0x46737365, 0x6f746361, 0xabab0072, 0x58454853,
26910         0x00000154, 0x00030050, 0x00000055, 0x01000071, 0x01002093, 0x01002094, 0x01001895, 0x01000896,
26911         0x01001897, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x01000073, 0x04000067,
26912         0x00102012, 0x00000000, 0x0000000b, 0x06000036, 0x00102012, 0x00000000, 0x0020800a, 0x00000000,
26913         0x00000000, 0x0100003e, 0x01000073, 0x04000067, 0x00102012, 0x00000001, 0x0000000c, 0x06000036,
26914         0x00102012, 0x00000001, 0x0020801a, 0x00000000, 0x00000000, 0x0100003e, 0x01000073, 0x04000067,
26915         0x00102012, 0x00000002, 0x0000000d, 0x06000036, 0x00102012, 0x00000002, 0x0020802a, 0x00000000,
26916         0x00000000, 0x0100003e, 0x01000073, 0x04000067, 0x00102012, 0x00000003, 0x0000000e, 0x06000036,
26917         0x00102012, 0x00000003, 0x0020803a, 0x00000000, 0x00000000, 0x0100003e, 0x01000073, 0x04000067,
26918         0x00102012, 0x00000004, 0x0000000f, 0x06000036, 0x00102012, 0x00000004, 0x0020800a, 0x00000000,
26919         0x00000001, 0x0100003e, 0x01000073, 0x04000067, 0x00102012, 0x00000005, 0x00000010, 0x06000036,
26920         0x00102012, 0x00000005, 0x0020801a, 0x00000000, 0x00000001, 0x0100003e,
26921     };
26922     static const D3D12_SHADER_BYTECODE hs_quad_cw = {hs_quad_cw_code, sizeof(hs_quad_cw_code)};
26923     static const struct vec4 quad[] =
26924     {
26925         {-1.0f, -1.0f, 0.0f, 1.0f},
26926         {-1.0f,  1.0f, 0.0f, 1.0f},
26927         { 1.0f, -1.0f, 0.0f, 1.0f},
26928         { 1.0f,  1.0f, 0.0f, 1.0f},
26929     };
26930     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
26931     {
26932         {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
26933     };
26934     static const D3D12_SO_DECLARATION_ENTRY so_declaration[] =
26935     {
26936         {0, "SV_POSITION", 0, 0, 4, 0},
26937     };
26938     unsigned int strides[] = {16};
26939     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
26940     static const BYTE zero_data[2048];
26941     static const struct triangle expected_quad_ccw[] =
26942     {
26943         {{{-1.0f, -1.0f, 0.0f, 1.0f},
26944           { 1.0f, -1.0f, 0.0f, 1.0f},
26945           {-1.0f,  1.0f, 0.0f, 1.0f}}},
26946         {{{-1.0f,  1.0f, 0.0f, 1.0f},
26947           { 1.0f, -1.0f, 0.0f, 1.0f},
26948           { 1.0f,  1.0f, 0.0f, 1.0f}}},
26949         {{{ 0.0f,  0.0f, 0.0f, 0.0f},
26950           { 0.0f,  0.0f, 0.0f, 0.0f},
26951           { 0.0f,  0.0f, 0.0f, 0.0f}}},
26952     };
26953     static const struct triangle expected_quad_cw[] =
26954     {
26955         {{{-1.0f, -1.0f, 0.0f, 1.0f},
26956           {-1.0f,  1.0f, 0.0f, 1.0f},
26957           { 1.0f, -1.0f, 0.0f, 1.0f}}},
26958         {{{-1.0f,  1.0f, 0.0f, 1.0f},
26959           { 1.0f,  1.0f, 0.0f, 1.0f},
26960           { 1.0f, -1.0f, 0.0f, 1.0f}}},
26961         {{{ 0.0f,  0.0f, 0.0f, 0.0f},
26962           { 0.0f,  0.0f, 0.0f, 0.0f},
26963           { 0.0f,  0.0f, 0.0f, 0.0f}}},
26964     };
26965     struct
26966     {
26967         float tess_factors[4];
26968         float inside_tess_factors[2];
26969         uint32_t padding[2];
26970     } constant;
26971 
26972     ID3D12Resource *vb, *so_buffer, *upload_buffer, *readback_buffer;
26973     D3D12_QUERY_DATA_SO_STATISTICS *so_statistics;
26974     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
26975     ID3D12GraphicsCommandList *command_list;
26976     D3D12_QUERY_HEAP_DESC query_heap_desc;
26977     D3D12_STREAM_OUTPUT_BUFFER_VIEW sobv;
26978     D3D12_INPUT_LAYOUT_DESC input_layout;
26979     struct test_context_desc desc;
26980     D3D12_VERTEX_BUFFER_VIEW vbv;
26981     struct resource_readback rb;
26982     ID3D12QueryHeap *query_heap;
26983     struct test_context context;
26984     ID3D12CommandQueue *queue;
26985     ID3D12Device *device;
26986     unsigned int i;
26987     HRESULT hr;
26988 
26989     memset(&desc, 0, sizeof(desc));
26990     desc.no_root_signature = true;
26991     if (!init_test_context(&context, &desc))
26992         return;
26993     device = context.device;
26994     command_list = context.list;
26995     queue = context.queue;
26996 
26997     query_heap_desc.Type = D3D12_QUERY_HEAP_TYPE_SO_STATISTICS;
26998     query_heap_desc.Count = 2;
26999     query_heap_desc.NodeMask = 0;
27000     hr = ID3D12Device_CreateQueryHeap(device, &query_heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
27001     if (hr == E_NOTIMPL)
27002     {
27003         skip("Stream output is not supported.\n");
27004         destroy_test_context(&context);
27005         return;
27006     }
27007     ok(hr == S_OK, "Failed to create query heap, hr %#x.\n", hr);
27008 
27009     context.root_signature = create_32bit_constants_root_signature_(__LINE__,
27010             device, 0, 6, D3D12_SHADER_VISIBILITY_HULL,
27011             D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT
27012             | D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT);
27013 
27014     input_layout.pInputElementDescs = layout_desc;
27015     input_layout.NumElements = ARRAY_SIZE(layout_desc);
27016 
27017     init_pipeline_state_desc(&pso_desc, context.root_signature,
27018             context.render_target_desc.Format, NULL, NULL, &input_layout);
27019     pso_desc.VS = vs;
27020     pso_desc.HS = hs_quad_cw;
27021     pso_desc.DS = ds;
27022     pso_desc.StreamOutput.NumEntries = ARRAY_SIZE(so_declaration);
27023     pso_desc.StreamOutput.pSODeclaration = so_declaration;
27024     pso_desc.StreamOutput.pBufferStrides = strides;
27025     pso_desc.StreamOutput.NumStrides = ARRAY_SIZE(strides);
27026     pso_desc.StreamOutput.RasterizedStream = 0;
27027     pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
27028 
27029     vb = create_upload_buffer(device, sizeof(quad), quad);
27030 
27031     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
27032     vbv.StrideInBytes = sizeof(*quad);
27033     vbv.SizeInBytes = sizeof(quad);
27034 
27035     upload_buffer = create_upload_buffer(device, sizeof(zero_data), &zero_data);
27036 
27037     so_buffer = create_default_buffer(device, sizeof(zero_data),
27038             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
27039 
27040     ID3D12GraphicsCommandList_CopyBufferRegion(command_list, so_buffer, 0,
27041             upload_buffer, 0, sizeof(zero_data));
27042     transition_resource_state(command_list, so_buffer,
27043             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_STREAM_OUT);
27044 
27045     sobv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(so_buffer);
27046     sobv.SizeInBytes = 1024;
27047     sobv.BufferFilledSizeLocation = sobv.BufferLocation + sobv.SizeInBytes;
27048 
27049     for (i = 0; i < ARRAY_SIZE(constant.tess_factors); ++i)
27050         constant.tess_factors[i] = 1.0f;
27051     for (i = 0; i < ARRAY_SIZE(constant.inside_tess_factors); ++i)
27052         constant.inside_tess_factors[i] = 1.0f;
27053 
27054     pso_desc.HS = hs_quad_ccw;
27055     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
27056             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
27057     ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
27058 
27059     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
27060 
27061     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
27062     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
27063     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
27064     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST);
27065     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
27066     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
27067     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 6, &constant, 0);
27068     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
27069     ID3D12GraphicsCommandList_SOSetTargets(command_list, 0, 1, &sobv);
27070     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
27071 
27072     transition_resource_state(command_list, context.render_target,
27073             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
27074     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xffffffff, 0);
27075 
27076     reset_command_list(command_list, context.allocator);
27077     transition_resource_state(command_list, context.render_target,
27078             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
27079 
27080     transition_resource_state(command_list, so_buffer,
27081             D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
27082     check_triangles(so_buffer, queue, command_list, expected_quad_ccw, ARRAY_SIZE(expected_quad_ccw));
27083 
27084     reset_command_list(command_list, context.allocator);
27085     transition_resource_state(command_list, so_buffer,
27086             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_COPY_DEST);
27087     ID3D12GraphicsCommandList_CopyBufferRegion(command_list, so_buffer, 0,
27088             upload_buffer, 0, sizeof(zero_data));
27089     transition_resource_state(command_list, so_buffer,
27090             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_STREAM_OUT);
27091 
27092     ID3D12PipelineState_Release(context.pipeline_state);
27093     pso_desc.HS = hs_quad_cw;
27094     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
27095             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
27096     ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
27097 
27098     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
27099 
27100     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
27101     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
27102     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
27103     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST);
27104     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
27105     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
27106     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 6, &constant, 0);
27107     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
27108     ID3D12GraphicsCommandList_SOSetTargets(command_list, 0, 1, &sobv);
27109     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
27110 
27111     transition_resource_state(command_list, context.render_target,
27112             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
27113     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
27114 
27115     reset_command_list(command_list, context.allocator);
27116     transition_resource_state(command_list, context.render_target,
27117             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
27118 
27119     transition_resource_state(command_list, so_buffer,
27120             D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
27121     check_triangles(so_buffer, queue, command_list, expected_quad_cw, ARRAY_SIZE(expected_quad_cw));
27122 
27123     reset_command_list(command_list, context.allocator);
27124     transition_resource_state(command_list, so_buffer,
27125             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_COPY_DEST);
27126     ID3D12GraphicsCommandList_CopyBufferRegion(command_list, so_buffer, 0,
27127             upload_buffer, 0, sizeof(zero_data));
27128     transition_resource_state(command_list, so_buffer,
27129             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_STREAM_OUT);
27130 
27131     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
27132     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
27133     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
27134     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST);
27135     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
27136     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
27137     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
27138     ID3D12GraphicsCommandList_SOSetTargets(command_list, 0, 1, &sobv);
27139 
27140     ID3D12GraphicsCommandList_BeginQuery(command_list, query_heap, D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0, 0);
27141 
27142     for (i = 0; i < ARRAY_SIZE(constant.tess_factors); ++i)
27143         constant.tess_factors[i] = 2.0f;
27144     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 6, &constant, 0);
27145     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
27146 
27147     constant.tess_factors[0] = 0.0f; /* A patch is discarded. */
27148     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 6, &constant, 0);
27149     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
27150 
27151     ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0, 0);
27152 
27153     ID3D12GraphicsCommandList_BeginQuery(command_list, query_heap, D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0, 1);
27154 
27155     constant.tess_factors[0] = 5.0f;
27156     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 6, &constant, 0);
27157     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
27158 
27159     ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0, 1);
27160 
27161     readback_buffer = create_readback_buffer(device, 2 * sizeof(*so_statistics));
27162     ID3D12GraphicsCommandList_ResolveQueryData(command_list,
27163             query_heap, D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0, 0, 2, readback_buffer, 0);
27164 
27165     get_buffer_readback_with_command_list(readback_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
27166     so_statistics = get_readback_data(&rb, 0, 0, 0, sizeof(*so_statistics));
27167     ok(so_statistics[0].NumPrimitivesWritten == 8, "Got unexpected primitives written %u.\n",
27168             (unsigned int)so_statistics[0].NumPrimitivesWritten);
27169     ok(so_statistics[0].PrimitivesStorageNeeded == 8, "Got unexpected primitives storage needed %u.\n",
27170             (unsigned int)so_statistics[0].PrimitivesStorageNeeded);
27171     ok(so_statistics[1].NumPrimitivesWritten == 11, "Got unexpected primitives written %u.\n",
27172             (unsigned int)so_statistics[1].NumPrimitivesWritten);
27173     ok(so_statistics[1].PrimitivesStorageNeeded == 11, "Got unexpected primitives storage needed %u.\n",
27174             (unsigned int)so_statistics[1].PrimitivesStorageNeeded);
27175     release_resource_readback(&rb);
27176 
27177     ID3D12Resource_Release(readback_buffer);
27178     ID3D12Resource_Release(so_buffer);
27179     ID3D12Resource_Release(upload_buffer);
27180     ID3D12Resource_Release(vb);
27181     ID3D12QueryHeap_Release(query_heap);
27182     destroy_test_context(&context);
27183 }
27184 
test_tessellation_dcl_index_range(void)27185 static void test_tessellation_dcl_index_range(void)
27186 {
27187     static const DWORD vs_code[] =
27188     {
27189 #if 0
27190         void main(float4 in_position : POSITION, out float4 out_position : SV_POSITION)
27191         {
27192             out_position = in_position;
27193         }
27194 #endif
27195         0x43425844, 0xa7a2f22d, 0x83ff2560, 0xe61638bd, 0x87e3ce90, 0x00000001, 0x000000d8, 0x00000003,
27196         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
27197         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
27198         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
27199         0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040,
27200         0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
27201         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
27202     };
27203     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
27204 #if 0
27205     struct point_data
27206     {
27207         float4 position : SV_POSITION;
27208     };
27209 
27210     struct patch_constant_data
27211     {
27212         float edges[4] : SV_TessFactor;
27213         float inside[2] : SV_InsideTessFactor;
27214     };
27215 
27216     patch_constant_data patch_constant(InputPatch<point_data, 4> input)
27217     {
27218         patch_constant_data output;
27219 
27220         output.edges[0] = 1.0f;
27221         output.edges[1] = 1.0f;
27222         output.edges[2] = 1.0f;
27223         output.edges[3] = 1.0f;
27224         output.inside[0] = 1.0f;
27225         output.inside[1] = 1.0f;
27226 
27227         return output;
27228     }
27229 
27230     [domain("quad")]
27231     [outputcontrolpoints(4)]
27232     [outputtopology("triangle_cw")]
27233     [partitioning("integer")]
27234     [patchconstantfunc("patch_constant")]
27235     point_data hs_main(InputPatch<point_data, 4> input,
27236             uint i : SV_OutputControlPointID)
27237     {
27238         return input[i];
27239     }
27240 
27241     [domain("quad")]
27242     point_data ds_main(patch_constant_data input,
27243             float2 tess_coord : SV_DomainLocation,
27244             const OutputPatch<point_data, 4> patch)
27245     {
27246         point_data output;
27247 
27248         float4 a = lerp(patch[0].position, patch[1].position, tess_coord.x);
27249         float4 b = lerp(patch[2].position, patch[3].position, tess_coord.x);
27250         output.position = lerp(a, b, tess_coord.y);
27251 
27252         return output;
27253     }
27254 #endif
27255     static const DWORD hs_code[] =
27256     {
27257         0x43425844, 0x0a619042, 0x424471f9, 0x9f0f4ff1, 0x065efacc, 0x00000001, 0x0000029c, 0x00000004,
27258         0x00000030, 0x00000064, 0x00000098, 0x0000015c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008,
27259         0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x505f5653, 0x5449534f,
27260         0x004e4f49, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001,
27261         0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x47534350, 0x000000bc,
27262         0x00000006, 0x00000008, 0x00000098, 0x00000000, 0x0000000b, 0x00000003, 0x00000000, 0x00000e01,
27263         0x00000098, 0x00000001, 0x0000000b, 0x00000003, 0x00000001, 0x00000e01, 0x00000098, 0x00000002,
27264         0x0000000b, 0x00000003, 0x00000002, 0x00000e01, 0x00000098, 0x00000003, 0x0000000b, 0x00000003,
27265         0x00000003, 0x00000e01, 0x000000a6, 0x00000000, 0x0000000c, 0x00000003, 0x00000004, 0x00000e01,
27266         0x000000a6, 0x00000001, 0x0000000c, 0x00000003, 0x00000005, 0x00000e01, 0x545f5653, 0x46737365,
27267         0x6f746361, 0x56530072, 0x736e495f, 0x54656469, 0x46737365, 0x6f746361, 0xabab0072, 0x58454853,
27268         0x00000138, 0x00030050, 0x0000004e, 0x01000071, 0x01002093, 0x01002094, 0x01001895, 0x01000896,
27269         0x01001897, 0x0100086a, 0x01000073, 0x02000099, 0x00000004, 0x0200005f, 0x00017000, 0x04000067,
27270         0x00102012, 0x00000000, 0x0000000b, 0x04000067, 0x00102012, 0x00000001, 0x0000000c, 0x04000067,
27271         0x00102012, 0x00000002, 0x0000000d, 0x04000067, 0x00102012, 0x00000003, 0x0000000e, 0x02000068,
27272         0x00000001, 0x0400005b, 0x00102012, 0x00000000, 0x00000004, 0x04000036, 0x00100012, 0x00000000,
27273         0x0001700a, 0x06000036, 0x00902012, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0100003e,
27274         0x01000073, 0x02000099, 0x00000002, 0x0200005f, 0x00017000, 0x04000067, 0x00102012, 0x00000004,
27275         0x0000000f, 0x04000067, 0x00102012, 0x00000005, 0x00000010, 0x02000068, 0x00000001, 0x0400005b,
27276         0x00102012, 0x00000004, 0x00000002, 0x04000036, 0x00100012, 0x00000000, 0x0001700a, 0x07000036,
27277         0x00d02012, 0x00000004, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0100003e,
27278     };
27279     static const D3D12_SHADER_BYTECODE hs = {hs_code, sizeof(hs_code)};
27280     static const DWORD ds_code[] =
27281     {
27282         0x43425844, 0x4f187d50, 0x6743fe93, 0x10dfbe63, 0xf8cfd202, 0x00000001, 0x00000284, 0x00000004,
27283         0x00000030, 0x00000064, 0x00000128, 0x0000015c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008,
27284         0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x505f5653, 0x5449534f,
27285         0x004e4f49, 0x47534350, 0x000000bc, 0x00000006, 0x00000008, 0x00000098, 0x00000000, 0x0000000b,
27286         0x00000003, 0x00000000, 0x00000001, 0x00000098, 0x00000001, 0x0000000b, 0x00000003, 0x00000001,
27287         0x00000001, 0x00000098, 0x00000002, 0x0000000b, 0x00000003, 0x00000002, 0x00000001, 0x00000098,
27288         0x00000003, 0x0000000b, 0x00000003, 0x00000003, 0x00000001, 0x000000a6, 0x00000000, 0x0000000c,
27289         0x00000003, 0x00000004, 0x00000001, 0x000000a6, 0x00000001, 0x0000000c, 0x00000003, 0x00000005,
27290         0x00000001, 0x545f5653, 0x46737365, 0x6f746361, 0x56530072, 0x736e495f, 0x54656469, 0x46737365,
27291         0x6f746361, 0xabab0072, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000,
27292         0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x58454853,
27293         0x00000120, 0x00040050, 0x00000048, 0x01002093, 0x01001895, 0x0100086a, 0x0200005f, 0x0001c032,
27294         0x0400005f, 0x002190f2, 0x00000004, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
27295         0x02000068, 0x00000002, 0x0a000000, 0x001000f2, 0x00000000, 0x80219e46, 0x00000041, 0x00000002,
27296         0x00000000, 0x00219e46, 0x00000003, 0x00000000, 0x09000032, 0x001000f2, 0x00000000, 0x0001c006,
27297         0x00100e46, 0x00000000, 0x00219e46, 0x00000002, 0x00000000, 0x0a000000, 0x001000f2, 0x00000001,
27298         0x80219e46, 0x00000041, 0x00000000, 0x00000000, 0x00219e46, 0x00000001, 0x00000000, 0x09000032,
27299         0x001000f2, 0x00000001, 0x0001c006, 0x00100e46, 0x00000001, 0x00219e46, 0x00000000, 0x00000000,
27300         0x08000000, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x80100e46, 0x00000041, 0x00000001,
27301         0x08000032, 0x001020f2, 0x00000000, 0x0001c556, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001,
27302         0x0100003e,
27303     };
27304     static const D3D12_SHADER_BYTECODE ds = {ds_code, sizeof(ds_code)};
27305     static const struct vec4 quad[] =
27306     {
27307         {-1.0f, -1.0f, 0.0f, 1.0f},
27308         {-1.0f,  1.0f, 0.0f, 1.0f},
27309         { 1.0f, -1.0f, 0.0f, 1.0f},
27310         { 1.0f,  1.0f, 0.0f, 1.0f},
27311     };
27312     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
27313     {
27314         {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
27315     };
27316     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
27317 
27318     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
27319     ID3D12GraphicsCommandList *command_list;
27320     D3D12_INPUT_LAYOUT_DESC input_layout;
27321     struct test_context_desc desc;
27322     D3D12_VERTEX_BUFFER_VIEW vbv;
27323     struct test_context context;
27324     ID3D12CommandQueue *queue;
27325     ID3D12Device *device;
27326     ID3D12Resource *vb;
27327     HRESULT hr;
27328 
27329     memset(&desc, 0, sizeof(desc));
27330     desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
27331     desc.no_pipeline = true;
27332     if (!init_test_context(&context, &desc))
27333         return;
27334     device = context.device;
27335     command_list = context.list;
27336     queue = context.queue;
27337 
27338     input_layout.pInputElementDescs = layout_desc;
27339     input_layout.NumElements = ARRAY_SIZE(layout_desc);
27340 
27341     init_pipeline_state_desc(&pso_desc, context.root_signature,
27342             context.render_target_desc.Format, NULL, NULL, &input_layout);
27343     pso_desc.VS = vs;
27344     pso_desc.HS = hs;
27345     pso_desc.DS = ds;
27346     pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
27347     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
27348             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
27349     ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
27350 
27351     vb = create_upload_buffer(device, sizeof(quad), quad);
27352 
27353     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
27354     vbv.StrideInBytes = sizeof(*quad);
27355     vbv.SizeInBytes = sizeof(quad);
27356 
27357     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
27358 
27359     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
27360     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
27361     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
27362     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST);
27363     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
27364     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
27365     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
27366     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
27367 
27368     transition_resource_state(command_list, context.render_target,
27369             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
27370     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
27371 
27372     ID3D12Resource_Release(vb);
27373     destroy_test_context(&context);
27374 }
27375 
test_hull_shader_control_point_phase(void)27376 static void test_hull_shader_control_point_phase(void)
27377 {
27378     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
27379     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
27380     ID3D12GraphicsCommandList *command_list;
27381     struct test_context_desc desc;
27382     struct test_context context;
27383     ID3D12CommandQueue *queue;
27384     HRESULT hr;
27385 
27386     static const DWORD vs_code[] =
27387     {
27388 #if 0
27389         void main()
27390         {
27391         }
27392 #endif
27393         0x43425844, 0x590b08ae, 0x11d28adb, 0x825a5628, 0x34c0c208, 0x00000001, 0x00000064, 0x00000003,
27394         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
27395         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000010, 0x00010050, 0x00000004, 0x0100086a,
27396         0x0100003e,
27397     };
27398     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
27399 #if 0
27400     struct data
27401     {
27402         float4 position : SV_Position;
27403     };
27404 
27405     struct patch_constant_data
27406     {
27407         float edges[3] : SV_TessFactor;
27408         float inside : SV_InsideTessFactor;
27409     };
27410 
27411     void patch_constant(out patch_constant_data output)
27412     {
27413         output.edges[0] = output.edges[1] = output.edges[2] = 1.0f;
27414         output.inside = 1.0f;
27415     }
27416 
27417     [domain("tri")]
27418     [outputcontrolpoints(3)]
27419     [partitioning("integer")]
27420     [outputtopology("triangle_cw")]
27421     [patchconstantfunc("patch_constant")]
27422     data hs_main(uint i : SV_OutputControlPointID)
27423     {
27424         data output;
27425 
27426         if (i == 0)
27427             output.position = float4(-1, 1, 0, 1);
27428         else if (i == 1)
27429             output.position = float4(3, 1, 0, 1);
27430         else
27431             output.position = float4(-1, -3, 0, 1);
27432 
27433         return output;
27434     }
27435 
27436     [domain("tri")]
27437     void ds_main(patch_constant_data input,
27438             float3 tess_coord : SV_DomainLocation,
27439             const OutputPatch<data, 3> patch,
27440             out data output)
27441     {
27442         uint index = uint(tess_coord.y + 2 * tess_coord.z);
27443         output.position = patch[index].position;
27444     }
27445 #endif
27446     static const DWORD hs_code[] =
27447     {
27448         0x43425844, 0x4204890e, 0x43f4f8e0, 0xbff7edfd, 0x0a48b715, 0x00000001, 0x0000028c, 0x00000004,
27449         0x00000030, 0x00000040, 0x00000074, 0x00000108, 0x4e475349, 0x00000008, 0x00000000, 0x00000008,
27450         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
27451         0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x47534350, 0x0000008c, 0x00000004,
27452         0x00000008, 0x00000068, 0x00000000, 0x0000000d, 0x00000003, 0x00000000, 0x00000e01, 0x00000068,
27453         0x00000001, 0x0000000d, 0x00000003, 0x00000001, 0x00000e01, 0x00000068, 0x00000002, 0x0000000d,
27454         0x00000003, 0x00000002, 0x00000e01, 0x00000076, 0x00000000, 0x0000000e, 0x00000003, 0x00000003,
27455         0x00000e01, 0x545f5653, 0x46737365, 0x6f746361, 0x56530072, 0x736e495f, 0x54656469, 0x46737365,
27456         0x6f746361, 0xabab0072, 0x58454853, 0x0000017c, 0x00030050, 0x0000005f, 0x01000071, 0x01000893,
27457         0x01001894, 0x01001095, 0x01000896, 0x01001897, 0x0100086a, 0x01000072, 0x0200005f, 0x00016000,
27458         0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x06000020, 0x00100012, 0x00000000,
27459         0x00016001, 0x00004001, 0x00000001, 0x0f000037, 0x001000f2, 0x00000000, 0x00100006, 0x00000000,
27460         0x00004002, 0x40400000, 0x3f800000, 0x00000000, 0x3f800000, 0x00004002, 0xbf800000, 0xc0400000,
27461         0x00000000, 0x3f800000, 0x0b000037, 0x001020f2, 0x00000000, 0x00016001, 0x00100e46, 0x00000000,
27462         0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x3f800000, 0x0100003e, 0x01000073, 0x02000099,
27463         0x00000003, 0x0200005f, 0x00017000, 0x04000067, 0x00102012, 0x00000000, 0x00000011, 0x04000067,
27464         0x00102012, 0x00000001, 0x00000012, 0x04000067, 0x00102012, 0x00000002, 0x00000013, 0x02000068,
27465         0x00000001, 0x0400005b, 0x00102012, 0x00000000, 0x00000003, 0x04000036, 0x00100012, 0x00000000,
27466         0x0001700a, 0x06000036, 0x00902012, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0100003e,
27467         0x01000073, 0x04000067, 0x00102012, 0x00000003, 0x00000014, 0x05000036, 0x00102012, 0x00000003,
27468         0x00004001, 0x3f800000, 0x0100003e,
27469     };
27470     static const D3D12_SHADER_BYTECODE hs = {hs_code, sizeof(hs_code)};
27471     static const DWORD ds_code[] =
27472     {
27473         0x43425844, 0x33c6120a, 0x2d46da82, 0x2c17dddf, 0x252ae7e0, 0x00000001, 0x000001c8, 0x00000004,
27474         0x00000030, 0x00000064, 0x000000f8, 0x0000012c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008,
27475         0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x505f5653, 0x7469736f,
27476         0x006e6f69, 0x47534350, 0x0000008c, 0x00000004, 0x00000008, 0x00000068, 0x00000000, 0x0000000d,
27477         0x00000003, 0x00000000, 0x00000001, 0x00000068, 0x00000001, 0x0000000d, 0x00000003, 0x00000001,
27478         0x00000001, 0x00000068, 0x00000002, 0x0000000d, 0x00000003, 0x00000002, 0x00000001, 0x00000076,
27479         0x00000000, 0x0000000e, 0x00000003, 0x00000003, 0x00000001, 0x545f5653, 0x46737365, 0x6f746361,
27480         0x56530072, 0x736e495f, 0x54656469, 0x46737365, 0x6f746361, 0xabab0072, 0x4e47534f, 0x0000002c,
27481         0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f,
27482         0x505f5653, 0x7469736f, 0x006e6f69, 0x58454853, 0x00000094, 0x00040050, 0x00000025, 0x01001893,
27483         0x01001095, 0x0100086a, 0x0200005f, 0x0001c062, 0x0400005f, 0x002190f2, 0x00000003, 0x00000000,
27484         0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x02000068, 0x00000001, 0x07000032, 0x00100012,
27485         0x00000000, 0x0001c02a, 0x00004001, 0x40000000, 0x0001c01a, 0x0500001c, 0x00100012, 0x00000000,
27486         0x0010000a, 0x00000000, 0x07000036, 0x001020f2, 0x00000000, 0x00a19e46, 0x0010000a, 0x00000000,
27487         0x00000000, 0x0100003e,
27488     };
27489     static const D3D12_SHADER_BYTECODE ds = {ds_code, sizeof(ds_code)};
27490 
27491     memset(&desc, 0, sizeof(desc));
27492     desc.no_pipeline = true;
27493     if (!init_test_context(&context, &desc))
27494         return;
27495     command_list = context.list;
27496     queue = context.queue;
27497 
27498     init_pipeline_state_desc(&pso_desc, context.root_signature,
27499             context.render_target_desc.Format, NULL, NULL, NULL);
27500     pso_desc.VS = vs;
27501     pso_desc.HS = hs;
27502     pso_desc.DS = ds;
27503     pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
27504     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
27505             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
27506     ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
27507 
27508     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
27509 
27510     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
27511     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
27512     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
27513     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST);
27514     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
27515     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
27516     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
27517 
27518     transition_resource_state(command_list, context.render_target,
27519             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
27520 
27521     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
27522 
27523     destroy_test_context(&context);
27524 }
27525 
test_hull_shader_fork_phase(void)27526 static void test_hull_shader_fork_phase(void)
27527 {
27528     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
27529     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
27530     ID3D12GraphicsCommandList *command_list;
27531     struct test_context_desc desc;
27532     struct test_context context;
27533     ID3D12CommandQueue *queue;
27534     HRESULT hr;
27535 
27536     static const DWORD vs_code[] =
27537     {
27538 #if 0
27539         float4 main() : SV_Position
27540         {
27541             return float4(-1, -1, 0, 0);
27542         }
27543 #endif
27544         0x43425844, 0x9f5f70e7, 0x57507df4, 0xbf1a4a34, 0xdb2531df, 0x00000001, 0x000000b8, 0x00000003,
27545         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
27546         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000,
27547         0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x58454853, 0x00000040, 0x00010050, 0x00000010,
27548         0x0100086a, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x08000036, 0x001020f2, 0x00000000,
27549         0x00004002, 0xbf800000, 0xbf800000, 0x00000000, 0x00000000, 0x0100003e,
27550     };
27551     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
27552 #if 0
27553     struct data
27554     {
27555         float4 position : SV_Position;
27556     };
27557 
27558     struct patch_constant_data
27559     {
27560         float edges[4] : SV_TessFactor;
27561         float inside[2] : SV_InsideTessFactor;
27562         float3 center : CENTER;
27563     };
27564 
27565     void patch_constant(OutputPatch<data, 4> control_points,
27566             out patch_constant_data output)
27567     {
27568         uint i;
27569 
27570         output = (patch_constant_data)0;
27571 
27572         for (i = 0; i < 4; ++i)
27573         {
27574             output.edges[i] = 1.0;
27575         }
27576 
27577         for (i = 0; i < 2; ++i)
27578         {
27579             output.inside[i] = 1.0;
27580         }
27581 
27582         for (i = 0; i < 4; ++i)
27583         {
27584             output.center += control_points[i].position.xyz;
27585         }
27586         output.center /= 4;
27587     }
27588 
27589     [domain("quad")]
27590     [outputcontrolpoints(4)]
27591     [partitioning("integer")]
27592     [outputtopology("triangle_cw")]
27593     [patchconstantfunc("patch_constant")]
27594     data hs_main(InputPatch<data, 1> input,
27595             uint i : SV_OutputControlPointID)
27596     {
27597         data o = (data)0;
27598         const float4 vertices[] =
27599         {
27600             float4(0, 0, 0, 1),
27601             float4(0, 2, 0, 1),
27602             float4(2, 0, 0, 1),
27603             float4(2, 2, 0, 1),
27604         };
27605 
27606         o.position = input[0].position + vertices[i];
27607 
27608         return o;
27609     }
27610 
27611     [domain("quad")]
27612     void ds_main(patch_constant_data input,
27613             float2 tess_coord : SV_DomainLocation,
27614             const OutputPatch<data, 4> patch,
27615             out float4 position : SV_Position,
27616             out float4 color : COLOR)
27617     {
27618         float4 a = lerp(patch[0].position, patch[1].position, tess_coord.x);
27619         float4 b = lerp(patch[2].position, patch[3].position, tess_coord.x);
27620         position = lerp(a, b, tess_coord.y);
27621 
27622         color = float4(input.center, 1.0);
27623     }
27624 #endif
27625     static const DWORD hs_code[] =
27626     {
27627         0x43425844, 0xcecdcc7a, 0x1e0454ae, 0x8c490947, 0x7e33bb11, 0x00000001, 0x000005a4, 0x00000004,
27628         0x00000030, 0x00000064, 0x00000098, 0x0000017c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008,
27629         0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x505f5653, 0x7469736f,
27630         0x006e6f69, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001,
27631         0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x47534350, 0x000000dc,
27632         0x00000007, 0x00000008, 0x000000b0, 0x00000000, 0x0000000b, 0x00000003, 0x00000000, 0x00000e01,
27633         0x000000be, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000010e, 0x000000b0, 0x00000001,
27634         0x0000000b, 0x00000003, 0x00000001, 0x00000e01, 0x000000b0, 0x00000002, 0x0000000b, 0x00000003,
27635         0x00000002, 0x00000e01, 0x000000b0, 0x00000003, 0x0000000b, 0x00000003, 0x00000003, 0x00000e01,
27636         0x000000c5, 0x00000000, 0x0000000c, 0x00000003, 0x00000004, 0x00000e01, 0x000000c5, 0x00000001,
27637         0x0000000c, 0x00000003, 0x00000005, 0x00000e01, 0x545f5653, 0x46737365, 0x6f746361, 0x45430072,
27638         0x5245544e, 0x5f565300, 0x69736e49, 0x65546564, 0x61467373, 0x726f7463, 0xababab00, 0x58454853,
27639         0x00000420, 0x00030050, 0x00000108, 0x01000071, 0x01000893, 0x01002094, 0x01001895, 0x01000896,
27640         0x01001897, 0x0100086a, 0x00001835, 0x00000012, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,
27641         0x3f800000, 0x00000000, 0x40000000, 0x00000000, 0x3f800000, 0x40000000, 0x00000000, 0x00000000,
27642         0x3f800000, 0x40000000, 0x40000000, 0x00000000, 0x01000072, 0x0200005f, 0x00016000, 0x0400005f,
27643         0x002010f2, 0x00000001, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001,
27644         0x04000036, 0x00100012, 0x00000000, 0x00016001, 0x06000036, 0x00100032, 0x00000000, 0x00909596,
27645         0x0010000a, 0x00000000, 0x08000036, 0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
27646         0x00000000, 0x3f800000, 0x08000000, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00201e46,
27647         0x00000000, 0x00000000, 0x0100003e, 0x01000073, 0x02000099, 0x00000004, 0x0200005f, 0x00017000,
27648         0x04000067, 0x00102012, 0x00000000, 0x0000000b, 0x04000067, 0x00102012, 0x00000001, 0x0000000c,
27649         0x04000067, 0x00102012, 0x00000002, 0x0000000d, 0x04000067, 0x00102012, 0x00000003, 0x0000000e,
27650         0x02000068, 0x00000001, 0x0400005b, 0x00102012, 0x00000000, 0x00000004, 0x04000036, 0x00100012,
27651         0x00000000, 0x0001700a, 0x06000036, 0x00902012, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000,
27652         0x0100003e, 0x01000073, 0x02000099, 0x00000002, 0x0200005f, 0x00017000, 0x04000067, 0x00102012,
27653         0x00000004, 0x0000000f, 0x04000067, 0x00102012, 0x00000005, 0x00000010, 0x02000068, 0x00000001,
27654         0x0400005b, 0x00102012, 0x00000004, 0x00000002, 0x04000036, 0x00100012, 0x00000000, 0x0001700a,
27655         0x07000036, 0x00d02012, 0x00000004, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0100003e,
27656         0x01000073, 0x0400005f, 0x0021a012, 0x00000004, 0x00000000, 0x03000065, 0x00102022, 0x00000000,
27657         0x02000068, 0x00000001, 0x09000000, 0x00100012, 0x00000000, 0x0021a00a, 0x00000001, 0x00000000,
27658         0x0021a00a, 0x00000000, 0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
27659         0x0021a00a, 0x00000002, 0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
27660         0x0021a00a, 0x00000003, 0x00000000, 0x07000038, 0x00102022, 0x00000000, 0x0010000a, 0x00000000,
27661         0x00004001, 0x3e800000, 0x0100003e, 0x01000073, 0x0400005f, 0x0021a022, 0x00000004, 0x00000000,
27662         0x03000065, 0x00102042, 0x00000000, 0x02000068, 0x00000001, 0x09000000, 0x00100012, 0x00000000,
27663         0x0021a01a, 0x00000001, 0x00000000, 0x0021a01a, 0x00000000, 0x00000000, 0x08000000, 0x00100012,
27664         0x00000000, 0x0010000a, 0x00000000, 0x0021a01a, 0x00000002, 0x00000000, 0x08000000, 0x00100012,
27665         0x00000000, 0x0010000a, 0x00000000, 0x0021a01a, 0x00000003, 0x00000000, 0x07000038, 0x00102042,
27666         0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3e800000, 0x0100003e, 0x01000073, 0x0400005f,
27667         0x0021a042, 0x00000004, 0x00000000, 0x03000065, 0x00102082, 0x00000000, 0x02000068, 0x00000001,
27668         0x09000000, 0x00100012, 0x00000000, 0x0021a02a, 0x00000001, 0x00000000, 0x0021a02a, 0x00000000,
27669         0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0021a02a, 0x00000002,
27670         0x00000000, 0x08000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0021a02a, 0x00000003,
27671         0x00000000, 0x07000038, 0x00102082, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3e800000,
27672         0x0100003e,
27673     };
27674     static const D3D12_SHADER_BYTECODE hs = {hs_code, sizeof(hs_code)};
27675     static const DWORD ds_code[] =
27676     {
27677         0x43425844, 0x6a721eb5, 0xa3ba6439, 0x3f31e765, 0x07e272c6, 0x00000001, 0x00000304, 0x00000004,
27678         0x00000030, 0x00000064, 0x00000148, 0x0000019c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008,
27679         0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x505f5653, 0x7469736f,
27680         0x006e6f69, 0x47534350, 0x000000dc, 0x00000007, 0x00000008, 0x000000b0, 0x00000000, 0x0000000b,
27681         0x00000003, 0x00000000, 0x00000001, 0x000000be, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
27682         0x00000e0e, 0x000000b0, 0x00000001, 0x0000000b, 0x00000003, 0x00000001, 0x00000001, 0x000000b0,
27683         0x00000002, 0x0000000b, 0x00000003, 0x00000002, 0x00000001, 0x000000b0, 0x00000003, 0x0000000b,
27684         0x00000003, 0x00000003, 0x00000001, 0x000000c5, 0x00000000, 0x0000000c, 0x00000003, 0x00000004,
27685         0x00000001, 0x000000c5, 0x00000001, 0x0000000c, 0x00000003, 0x00000005, 0x00000001, 0x545f5653,
27686         0x46737365, 0x6f746361, 0x45430072, 0x5245544e, 0x5f565300, 0x69736e49, 0x65546564, 0x61467373,
27687         0x726f7463, 0xababab00, 0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000,
27688         0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003,
27689         0x00000001, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x4f4c4f43, 0xabab0052, 0x58454853,
27690         0x00000160, 0x00040050, 0x00000058, 0x01002093, 0x01001895, 0x0100086a, 0x0300005f, 0x0011b0e2,
27691         0x00000000, 0x0200005f, 0x0001c032, 0x0400005f, 0x002190f2, 0x00000004, 0x00000000, 0x04000067,
27692         0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x02000068, 0x00000002,
27693         0x0a000000, 0x001000f2, 0x00000000, 0x80219e46, 0x00000041, 0x00000002, 0x00000000, 0x00219e46,
27694         0x00000003, 0x00000000, 0x09000032, 0x001000f2, 0x00000000, 0x0001c006, 0x00100e46, 0x00000000,
27695         0x00219e46, 0x00000002, 0x00000000, 0x0a000000, 0x001000f2, 0x00000001, 0x80219e46, 0x00000041,
27696         0x00000000, 0x00000000, 0x00219e46, 0x00000001, 0x00000000, 0x09000032, 0x001000f2, 0x00000001,
27697         0x0001c006, 0x00100e46, 0x00000001, 0x00219e46, 0x00000000, 0x00000000, 0x08000000, 0x001000f2,
27698         0x00000000, 0x00100e46, 0x00000000, 0x80100e46, 0x00000041, 0x00000001, 0x08000032, 0x001020f2,
27699         0x00000000, 0x0001c556, 0x00100e46, 0x00000000, 0x00100e46, 0x00000001, 0x05000036, 0x00102072,
27700         0x00000001, 0x0011b796, 0x00000000, 0x05000036, 0x00102082, 0x00000001, 0x00004001, 0x3f800000,
27701         0x0100003e,
27702     };
27703     static const D3D12_SHADER_BYTECODE ds = {ds_code, sizeof(ds_code)};
27704     static const DWORD ps_code[] =
27705     {
27706 #if 0
27707         float4 main(in float4 p : SV_Position, in float4 color : COLOR) : SV_Target
27708         {
27709             return color;
27710         }
27711 #endif
27712         0x43425844, 0xbd83f517, 0x8974e87a, 0xaf402223, 0xaec7f351, 0x00000001, 0x000000f8, 0x00000003,
27713         0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
27714         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000,
27715         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x4f4c4f43, 0xabab0052,
27716         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
27717         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000003c, 0x00000050,
27718         0x0000000f, 0x0100086a, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
27719         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e,
27720     };
27721     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
27722 
27723     memset(&desc, 0, sizeof(desc));
27724     desc.no_pipeline = true;
27725     if (!init_test_context(&context, &desc))
27726         return;
27727     command_list = context.list;
27728     queue = context.queue;
27729 
27730     init_pipeline_state_desc(&pso_desc, context.root_signature,
27731             context.render_target_desc.Format, NULL, NULL, NULL);
27732     pso_desc.VS = vs;
27733     pso_desc.HS = hs;
27734     pso_desc.DS = ds;
27735     pso_desc.PS = ps;
27736     pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
27737     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
27738             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
27739     ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
27740 
27741     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
27742 
27743     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
27744     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
27745     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
27746     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST);
27747     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
27748     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
27749     ID3D12GraphicsCommandList_DrawInstanced(command_list, 1, 1, 0, 0);
27750 
27751     transition_resource_state(command_list, context.render_target,
27752             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
27753     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff000000, 0);
27754 
27755     destroy_test_context(&context);
27756 }
27757 
test_line_tessellation(void)27758 static void test_line_tessellation(void)
27759 {
27760     ID3D12Resource *vb, *so_buffer, *readback_buffer;
27761     D3D12_QUERY_DATA_SO_STATISTICS *so_statistics;
27762     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
27763     ID3D12GraphicsCommandList *command_list;
27764     D3D12_QUERY_HEAP_DESC query_heap_desc;
27765     D3D12_STREAM_OUTPUT_BUFFER_VIEW sobv;
27766     D3D12_INPUT_LAYOUT_DESC input_layout;
27767     struct test_context_desc desc;
27768     D3D12_VERTEX_BUFFER_VIEW vbv;
27769     struct resource_readback rb;
27770     ID3D12QueryHeap *query_heap;
27771     struct test_context context;
27772     const struct vec4 *expected;
27773     ID3D12CommandQueue *queue;
27774     struct vec4 *data;
27775     bool broken_warp;
27776     unsigned int i;
27777     HRESULT hr;
27778 
27779 #if 0
27780     struct data
27781     {
27782         float4 position : SV_Position;
27783         float3 color : COLOR;
27784         float line_density : LINE_DENSITY;
27785         float line_detail : LINE_DETAIL;
27786     };
27787 
27788     data vs_main(data input)
27789     {
27790         return input;
27791     }
27792 
27793     struct patch_constant_data
27794     {
27795         float tess_factor[2] : SV_TessFactor;
27796         float3 color : COLOR;
27797         uint prim_id : PRIMITIVE_ID;
27798     };
27799 
27800     void patch_constant(OutputPatch<data, 1> control_points,
27801             uint prim_id : SV_PrimitiveID,
27802             out patch_constant_data output)
27803     {
27804         output.tess_factor[0] = control_points[0].line_density;
27805         output.tess_factor[1] = control_points[0].line_detail;
27806         output.color = control_points[0].color;
27807         output.prim_id = prim_id;
27808     }
27809 
27810     [domain("isoline")]
27811     [outputcontrolpoints(1)]
27812     [partitioning("integer")]
27813     [outputtopology("line")]
27814     [patchconstantfunc("patch_constant")]
27815     data hs_main(InputPatch<data, 1> input)
27816     {
27817         return input[0];
27818     }
27819 
27820     [domain("isoline")]
27821     void ds_main(patch_constant_data input,
27822             float tess_factor[2] : SV_TessFactor,
27823             float2 tess_coord : SV_DomainLocation,
27824             float3 color : COLOR,
27825             uint prim_id : PRIMITIVE_ID,
27826             const OutputPatch<data, 1> patch,
27827             out float4 position : SV_Position,
27828             out float4 out_color : COLOR,
27829             out float4 out_prim_id : PRIMITIVE_ID)
27830     {
27831         position = patch[0].position;
27832         out_color = float4(color, 1.0);
27833         out_prim_id = prim_id;
27834     }
27835 #endif
27836     static const DWORD vs_code[] =
27837     {
27838         0x43425844, 0x43d2f821, 0xc4bcdf60, 0xadbf5ed0, 0xe55b715d, 0x00000001, 0x00000230, 0x00000003,
27839         0x0000002c, 0x000000c8, 0x00000164, 0x4e475349, 0x00000094, 0x00000004, 0x00000008, 0x00000068,
27840         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000074, 0x00000000, 0x00000000,
27841         0x00000003, 0x00000001, 0x00000707, 0x0000007a, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
27842         0x00000101, 0x00000087, 0x00000000, 0x00000000, 0x00000003, 0x00000003, 0x00000101, 0x505f5653,
27843         0x7469736f, 0x006e6f69, 0x4f4c4f43, 0x494c0052, 0x445f454e, 0x49534e45, 0x4c005954, 0x5f454e49,
27844         0x41544544, 0xab004c49, 0x4e47534f, 0x00000094, 0x00000004, 0x00000008, 0x00000068, 0x00000000,
27845         0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000074, 0x00000000, 0x00000000, 0x00000003,
27846         0x00000001, 0x00000807, 0x0000007a, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000708,
27847         0x00000087, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000e01, 0x505f5653, 0x7469736f,
27848         0x006e6f69, 0x4f4c4f43, 0x494c0052, 0x445f454e, 0x49534e45, 0x4c005954, 0x5f454e49, 0x41544544,
27849         0xab004c49, 0x58454853, 0x000000c4, 0x00010050, 0x00000031, 0x0100086a, 0x0300005f, 0x001010f2,
27850         0x00000000, 0x0300005f, 0x00101072, 0x00000001, 0x0300005f, 0x00101012, 0x00000002, 0x0300005f,
27851         0x00101012, 0x00000003, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102072,
27852         0x00000001, 0x03000065, 0x00102082, 0x00000001, 0x03000065, 0x00102012, 0x00000002, 0x05000036,
27853         0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x00102072, 0x00000001, 0x00101246,
27854         0x00000001, 0x05000036, 0x00102082, 0x00000001, 0x0010100a, 0x00000002, 0x05000036, 0x00102012,
27855         0x00000002, 0x0010100a, 0x00000003, 0x0100003e,
27856     };
27857     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
27858     static const DWORD hs_code[] =
27859     {
27860         0x43425844, 0x130f1b8c, 0x02c24095, 0x18ab42ad, 0xbb861b50, 0x00000001, 0x00000448, 0x00000004,
27861         0x00000030, 0x000000cc, 0x00000168, 0x000001fc, 0x4e475349, 0x00000094, 0x00000004, 0x00000008,
27862         0x00000068, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x00000074, 0x00000000,
27863         0x00000000, 0x00000003, 0x00000001, 0x00000707, 0x0000007a, 0x00000000, 0x00000000, 0x00000003,
27864         0x00000001, 0x00000808, 0x00000087, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000101,
27865         0x505f5653, 0x7469736f, 0x006e6f69, 0x4f4c4f43, 0x494c0052, 0x445f454e, 0x49534e45, 0x4c005954,
27866         0x5f454e49, 0x41544544, 0xab004c49, 0x4e47534f, 0x00000094, 0x00000004, 0x00000008, 0x00000068,
27867         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000074, 0x00000000, 0x00000000,
27868         0x00000003, 0x00000001, 0x00000807, 0x0000007a, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
27869         0x00000708, 0x00000087, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000e01, 0x505f5653,
27870         0x7469736f, 0x006e6f69, 0x4f4c4f43, 0x494c0052, 0x445f454e, 0x49534e45, 0x4c005954, 0x5f454e49,
27871         0x41544544, 0xab004c49, 0x47534350, 0x0000008c, 0x00000004, 0x00000008, 0x00000068, 0x00000000,
27872         0x00000010, 0x00000003, 0x00000000, 0x00000e01, 0x00000076, 0x00000000, 0x00000000, 0x00000003,
27873         0x00000000, 0x0000010e, 0x00000068, 0x00000001, 0x0000000f, 0x00000003, 0x00000001, 0x00000e01,
27874         0x0000007c, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000d02, 0x545f5653, 0x46737365,
27875         0x6f746361, 0x4f430072, 0x00524f4c, 0x4d495250, 0x56495449, 0x44495f45, 0xababab00, 0x58454853,
27876         0x00000244, 0x00030050, 0x00000091, 0x01000071, 0x01000893, 0x01000894, 0x01000895, 0x01000896,
27877         0x01001097, 0x0100086a, 0x01000072, 0x0400005f, 0x002010f2, 0x00000001, 0x00000000, 0x0400005f,
27878         0x00201072, 0x00000001, 0x00000001, 0x0400005f, 0x00201082, 0x00000001, 0x00000001, 0x0400005f,
27879         0x00201012, 0x00000001, 0x00000002, 0x03000065, 0x001020f2, 0x00000000, 0x03000065, 0x00102072,
27880         0x00000001, 0x03000065, 0x00102082, 0x00000001, 0x03000065, 0x00102012, 0x00000002, 0x06000036,
27881         0x001020f2, 0x00000000, 0x00201e46, 0x00000000, 0x00000000, 0x06000036, 0x001020f2, 0x00000001,
27882         0x00201e46, 0x00000000, 0x00000001, 0x06000036, 0x00102012, 0x00000002, 0x0020100a, 0x00000000,
27883         0x00000002, 0x0100003e, 0x01000073, 0x0400005f, 0x0021a082, 0x00000001, 0x00000001, 0x04000067,
27884         0x00102012, 0x00000000, 0x00000016, 0x06000036, 0x00102012, 0x00000000, 0x0021a03a, 0x00000000,
27885         0x00000001, 0x0100003e, 0x01000073, 0x0400005f, 0x0021a012, 0x00000001, 0x00000002, 0x04000067,
27886         0x00102012, 0x00000001, 0x00000015, 0x06000036, 0x00102012, 0x00000001, 0x0021a00a, 0x00000000,
27887         0x00000002, 0x0100003e, 0x01000073, 0x0400005f, 0x0021a012, 0x00000001, 0x00000001, 0x03000065,
27888         0x00102022, 0x00000000, 0x06000036, 0x00102022, 0x00000000, 0x0021a00a, 0x00000000, 0x00000001,
27889         0x0100003e, 0x01000073, 0x0400005f, 0x0021a022, 0x00000001, 0x00000001, 0x03000065, 0x00102042,
27890         0x00000000, 0x06000036, 0x00102042, 0x00000000, 0x0021a01a, 0x00000000, 0x00000001, 0x0100003e,
27891         0x01000073, 0x0400005f, 0x0021a042, 0x00000001, 0x00000001, 0x03000065, 0x00102082, 0x00000000,
27892         0x06000036, 0x00102082, 0x00000000, 0x0021a02a, 0x00000000, 0x00000001, 0x0100003e, 0x01000073,
27893         0x0200005f, 0x0000b000, 0x03000065, 0x00102022, 0x00000001, 0x04000036, 0x00102022, 0x00000001,
27894         0x0000b001, 0x0100003e,
27895     };
27896     static const D3D12_SHADER_BYTECODE hs = {hs_code, sizeof(hs_code)};
27897     static const DWORD ds_code[] =
27898     {
27899         0x43425844, 0xc78d05dd, 0x4b270467, 0xb480a2fb, 0x02f0edc7, 0x00000001, 0x0000029c, 0x00000004,
27900         0x00000030, 0x000000cc, 0x00000160, 0x000001d8, 0x4e475349, 0x00000094, 0x00000004, 0x00000008,
27901         0x00000068, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x00000074, 0x00000000,
27902         0x00000000, 0x00000003, 0x00000001, 0x00000007, 0x0000007a, 0x00000000, 0x00000000, 0x00000003,
27903         0x00000001, 0x00000008, 0x00000087, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000001,
27904         0x505f5653, 0x7469736f, 0x006e6f69, 0x4f4c4f43, 0x494c0052, 0x445f454e, 0x49534e45, 0x4c005954,
27905         0x5f454e49, 0x41544544, 0xab004c49, 0x47534350, 0x0000008c, 0x00000004, 0x00000008, 0x00000068,
27906         0x00000000, 0x00000010, 0x00000003, 0x00000000, 0x00000001, 0x00000076, 0x00000000, 0x00000000,
27907         0x00000003, 0x00000000, 0x00000e0e, 0x00000068, 0x00000001, 0x0000000f, 0x00000003, 0x00000001,
27908         0x00000001, 0x0000007c, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000202, 0x545f5653,
27909         0x46737365, 0x6f746361, 0x4f430072, 0x00524f4c, 0x4d495250, 0x56495449, 0x44495f45, 0xababab00,
27910         0x4e47534f, 0x00000070, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, 0x00000003,
27911         0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
27912         0x00000062, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x7469736f,
27913         0x006e6f69, 0x4f4c4f43, 0x52500052, 0x54494d49, 0x5f455649, 0xab004449, 0x58454853, 0x000000bc,
27914         0x00040050, 0x0000002f, 0x01000893, 0x01000895, 0x0100086a, 0x0300005f, 0x0011b0e2, 0x00000000,
27915         0x0300005f, 0x0011b022, 0x00000001, 0x0400005f, 0x002190f2, 0x00000001, 0x00000000, 0x04000067,
27916         0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x03000065, 0x001020f2,
27917         0x00000002, 0x06000036, 0x001020f2, 0x00000000, 0x00219e46, 0x00000000, 0x00000000, 0x05000036,
27918         0x00102072, 0x00000001, 0x0011b796, 0x00000000, 0x05000036, 0x00102082, 0x00000001, 0x00004001,
27919         0x3f800000, 0x05000056, 0x001020f2, 0x00000002, 0x0011b556, 0x00000001, 0x0100003e,
27920     };
27921     static const D3D12_SHADER_BYTECODE ds = {ds_code, sizeof(ds_code)};
27922     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
27923     {
27924         {"SV_POSITION",  0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0,  0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
27925         {"COLOR",        0, DXGI_FORMAT_R32G32B32_FLOAT,    0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
27926         {"LINE_DENSITY", 0, DXGI_FORMAT_R32_FLOAT,          0, 32, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
27927         {"LINE_DETAIL",  0, DXGI_FORMAT_R32_FLOAT,          0, 36, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
27928     };
27929     static const D3D12_SO_DECLARATION_ENTRY so_declaration[] =
27930     {
27931         {0, "SV_POSITION",  0, 0, 4, 0},
27932         {0, "COLOR",        0, 0, 4, 0},
27933         {0, "PRIMITIVE_ID", 0, 0, 4, 0},
27934     };
27935     unsigned int strides[] = {48};
27936     static const struct
27937     {
27938         struct vec4 position;
27939         struct vec4 color;
27940         float line_density;
27941         float line_detail;
27942     }
27943     vertices[] =
27944     {
27945         {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 0.0f}, 1.0f, 1.0f},
27946         {{1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.5f, 0.0f}, 2.0f, 1.0f},
27947         {{2.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f}, 1.0f, 2.0f},
27948         {{3.0f, 0.0f, 0.0f, 1.0f}, {0.5f, 0.5f, 0.5f}, 2.0f, 2.0f},
27949     };
27950     static const struct vec4 expected_data[] =
27951     {
27952         {0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 0.0f},
27953         {0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 0.0f},
27954 
27955         {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.5f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f},
27956         {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.5f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f},
27957         {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.5f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f},
27958         {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.5f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f},
27959 
27960         {2.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {2.0f, 2.0f, 2.0f, 2.0f},
27961         {2.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {2.0f, 2.0f, 2.0f, 2.0f},
27962         {2.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {2.0f, 2.0f, 2.0f, 2.0f},
27963         {2.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {2.0f, 2.0f, 2.0f, 2.0f},
27964 
27965         {3.0f, 0.0f, 0.0f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f}, {3.0f, 3.0f, 3.0f, 3.0f},
27966         {3.0f, 0.0f, 0.0f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f}, {3.0f, 3.0f, 3.0f, 3.0f},
27967         {3.0f, 0.0f, 0.0f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f}, {3.0f, 3.0f, 3.0f, 3.0f},
27968         {3.0f, 0.0f, 0.0f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f}, {3.0f, 3.0f, 3.0f, 3.0f},
27969         {3.0f, 0.0f, 0.0f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f}, {3.0f, 3.0f, 3.0f, 3.0f},
27970         {3.0f, 0.0f, 0.0f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f}, {3.0f, 3.0f, 3.0f, 3.0f},
27971         {3.0f, 0.0f, 0.0f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f}, {3.0f, 3.0f, 3.0f, 3.0f},
27972         {3.0f, 0.0f, 0.0f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f}, {3.0f, 3.0f, 3.0f, 3.0f},
27973     };
27974 
27975     memset(&desc, 0, sizeof(desc));
27976     desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT
27977             | D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT;
27978     desc.no_pipeline = true;
27979     if (!init_test_context(&context, &desc))
27980         return;
27981     command_list = context.list;
27982     queue = context.queue;
27983 
27984     query_heap_desc.Type = D3D12_QUERY_HEAP_TYPE_SO_STATISTICS;
27985     query_heap_desc.Count = 2;
27986     query_heap_desc.NodeMask = 0;
27987     hr = ID3D12Device_CreateQueryHeap(context.device, &query_heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
27988     if (hr == E_NOTIMPL)
27989     {
27990         skip("Stream output is not supported.\n");
27991         destroy_test_context(&context);
27992         return;
27993     }
27994     ok(hr == S_OK, "Failed to create query heap, hr %#x.\n", hr);
27995 
27996     input_layout.pInputElementDescs = layout_desc;
27997     input_layout.NumElements = ARRAY_SIZE(layout_desc);
27998     init_pipeline_state_desc(&pso_desc, context.root_signature,
27999             DXGI_FORMAT_UNKNOWN, NULL, NULL, &input_layout);
28000     pso_desc.VS = vs;
28001     pso_desc.HS = hs;
28002     pso_desc.DS = ds;
28003     memset(&pso_desc.PS, 0, sizeof(pso_desc.PS));
28004     pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
28005     pso_desc.StreamOutput.NumEntries = ARRAY_SIZE(so_declaration);
28006     pso_desc.StreamOutput.pSODeclaration = so_declaration;
28007     pso_desc.StreamOutput.pBufferStrides = strides;
28008     pso_desc.StreamOutput.NumStrides = ARRAY_SIZE(strides);
28009     pso_desc.StreamOutput.RasterizedStream = D3D12_SO_NO_RASTERIZED_STREAM;
28010     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
28011             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
28012     ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
28013 
28014     vb = create_upload_buffer(context.device, sizeof(vertices), vertices);
28015     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
28016     vbv.StrideInBytes = sizeof(*vertices);
28017     vbv.SizeInBytes = sizeof(vertices);
28018 
28019     so_buffer = create_default_buffer(context.device, 4096,
28020             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_STREAM_OUT);
28021     sobv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(so_buffer);
28022     sobv.SizeInBytes = 1024;
28023     sobv.BufferFilledSizeLocation = sobv.BufferLocation + sobv.SizeInBytes;
28024 
28025     ID3D12GraphicsCommandList_BeginQuery(command_list, query_heap, D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0, 0);
28026 
28027     ID3D12GraphicsCommandList_SOSetTargets(command_list, 0, 1, &sobv);
28028 
28029     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
28030     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
28031     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST);
28032     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
28033     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
28034     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
28035     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
28036 
28037     ID3D12GraphicsCommandList_EndQuery(command_list, query_heap, D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0, 0);
28038 
28039     readback_buffer = create_readback_buffer(context.device, sizeof(*so_statistics));
28040     ID3D12GraphicsCommandList_ResolveQueryData(command_list,
28041             query_heap, D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0, 0, 1, readback_buffer, 0);
28042 
28043     get_buffer_readback_with_command_list(readback_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
28044     so_statistics = get_readback_data(&rb, 0, 0, 0, sizeof(*so_statistics));
28045     broken_warp = broken_on_warp(so_statistics[0].NumPrimitivesWritten != 9);
28046     ok(so_statistics[0].NumPrimitivesWritten == 9 || broken_warp, "Got unexpected primitives written %u.\n",
28047             (unsigned int)so_statistics[0].NumPrimitivesWritten);
28048     ok(so_statistics[0].PrimitivesStorageNeeded == 9 || broken_warp, "Got unexpected primitives storage needed %u.\n",
28049             (unsigned int)so_statistics[0].PrimitivesStorageNeeded);
28050     release_resource_readback(&rb);
28051 
28052     if (broken_warp)
28053     {
28054         skip("Broken on WARP.\n");
28055         goto done;
28056     }
28057 
28058     reset_command_list(command_list, context.allocator);
28059     transition_resource_state(command_list, so_buffer,
28060             D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
28061     get_buffer_readback_with_command_list(so_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
28062     for (i = 0; i < ARRAY_SIZE(expected_data) / 3 ; ++i)
28063     {
28064         data = get_readback_data(&rb, i, 0, 0, 3 * sizeof(*data));
28065         expected = &expected_data[3 * i + 0];
28066         ok(compare_vec4(data, expected, 1),
28067                 "Got position {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e} at %u.\n",
28068                 data->x, data->y, data->z, data->w, expected->x, expected->y, expected->z, expected->w, i);
28069         ++data;
28070         expected = &expected_data[3 * i + 1];
28071         bug_if(is_nvidia_device(context.device))
28072         ok(compare_vec4(data, expected, 1),
28073                 "Got color {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e} at %u.\n",
28074                 data->x, data->y, data->z, data->w, expected->x, expected->y, expected->z, expected->w, i);
28075         ++data;
28076         expected = &expected_data[3 * i + 2];
28077         ok(compare_vec4(data, expected, 1),
28078                 "Got primitive ID {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e} at %u.\n",
28079                 data->x, data->y, data->z, data->w, expected->x, expected->y, expected->z, expected->w, i);
28080     }
28081     release_resource_readback(&rb);
28082 
28083 done:
28084     ID3D12QueryHeap_Release(query_heap);
28085     ID3D12Resource_Release(readback_buffer);
28086     ID3D12Resource_Release(so_buffer);
28087     ID3D12Resource_Release(vb);
28088     destroy_test_context(&context);
28089 }
28090 
test_tessellation_primitive_id(void)28091 static void test_tessellation_primitive_id(void)
28092 {
28093     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
28094     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
28095     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
28096     D3D12_ROOT_PARAMETER root_parameters[1];
28097     ID3D12GraphicsCommandList *command_list;
28098     D3D12_INPUT_LAYOUT_DESC input_layout;
28099     struct test_context_desc desc;
28100     D3D12_VERTEX_BUFFER_VIEW vbv;
28101     struct test_context context;
28102     ID3D12Resource *raw_buffer;
28103     ID3D12CommandQueue *queue;
28104     ID3D12Resource *vb;
28105     HRESULT hr;
28106 
28107 #if 0
28108     ByteAddressBuffer b;
28109 
28110     struct data
28111     {
28112         float4 position : POSITION;
28113         float ref_buffer_data : REF_BUFFER_DATA;
28114     };
28115 
28116     struct ds_data
28117     {
28118         float4 position : POSITION;
28119         float ref_buffer_data : REF_BUFFER_DATA;
28120         uint primitive_id : PRIM_ID;
28121         uint invocation_id : CP_ID;
28122     };
28123 
28124     struct ps_data
28125     {
28126         float4 position : SV_POSITION;
28127         float4 color : COLOR;
28128     };
28129 
28130     struct patch_constant_data
28131     {
28132         float edges[3] : SV_TessFactor;
28133         float inside : SV_InsideTessFactor;
28134         float buffer_data : BUFFER_DATA;
28135         uint primitive_id : PATCH_PRIM_ID;
28136     };
28137 
28138     data vs_main(in data input)
28139     {
28140         return input;
28141     }
28142 
28143     void patch_constant(uint prim_id : SV_PrimitiveID, out patch_constant_data output)
28144     {
28145         output.edges[0] = output.edges[1] = output.edges[2] = 4.0f;
28146         output.inside = 4.0f;
28147         output.buffer_data = b.Load(4 * prim_id);
28148         output.primitive_id = prim_id;
28149     }
28150 
28151     [domain("tri")]
28152     [outputcontrolpoints(3)]
28153     [partitioning("integer")]
28154     [outputtopology("triangle_cw")]
28155     [patchconstantfunc("patch_constant")]
28156     ds_data hs_main(const InputPatch<data, 3> input,
28157             uint prim_id : SV_PrimitiveID, uint i : SV_OutputControlPointID)
28158     {
28159         ds_data output;
28160         output.position = input[i].position;
28161         output.ref_buffer_data = input[i].ref_buffer_data;
28162         output.primitive_id = prim_id;
28163         output.invocation_id = i;
28164         return output;
28165     }
28166 
28167     [domain("tri")]
28168     void ds_main(patch_constant_data input,
28169             float3 tess_coord : SV_DomainLocation,
28170             const OutputPatch<ds_data, 3> patch,
28171             out ps_data output)
28172     {
28173         uint i;
28174 
28175         output.position = tess_coord.x * patch[0].position
28176                 + tess_coord.y * patch[1].position
28177                 + tess_coord.z * patch[2].position;
28178 
28179         for (i = 0; i < 3; ++i)
28180         {
28181             if (patch[i].ref_buffer_data != input.buffer_data)
28182             {
28183                 output.color = float4(1, patch[i].ref_buffer_data / 255.0f, input.buffer_data / 255.0f, 0);
28184                 return;
28185             }
28186         }
28187 
28188         for (i = 0; i < 3; ++i)
28189         {
28190             if (patch[i].primitive_id != input.primitive_id)
28191             {
28192                 output.color = float4(1, 0, 1, 1);
28193                 return;
28194             }
28195         }
28196 
28197         if (patch[0].invocation_id != 0 || patch[1].invocation_id != 1 || patch[2].invocation_id != 2)
28198         {
28199             output.color = float4(1, 1, 0, 1);
28200             return;
28201         }
28202 
28203         output.color = float4(0, 1, 0, 1);
28204     }
28205 #endif
28206     static const DWORD vs_code[] =
28207     {
28208         0x43425844, 0x1cf34a89, 0x09f0ca02, 0x1d9d7e25, 0x4161cddd, 0x00000001, 0x00000154, 0x00000003,
28209         0x0000002c, 0x00000088, 0x000000e4, 0x4e475349, 0x00000054, 0x00000002, 0x00000008, 0x00000038,
28210         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, 0x00000000, 0x00000000,
28211         0x00000003, 0x00000001, 0x00000101, 0x49534f50, 0x4e4f4954, 0x46455200, 0x4655425f, 0x5f524546,
28212         0x41544144, 0xababab00, 0x4e47534f, 0x00000054, 0x00000002, 0x00000008, 0x00000038, 0x00000000,
28213         0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x00000041, 0x00000000, 0x00000000, 0x00000003,
28214         0x00000001, 0x00000e01, 0x49534f50, 0x4e4f4954, 0x46455200, 0x4655425f, 0x5f524546, 0x41544144,
28215         0xababab00, 0x58454853, 0x00000068, 0x00010050, 0x0000001a, 0x0100086a, 0x0300005f, 0x001010f2,
28216         0x00000000, 0x0300005f, 0x00101012, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x03000065,
28217         0x00102012, 0x00000001, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x05000036,
28218         0x00102012, 0x00000001, 0x0010100a, 0x00000001, 0x0100003e,
28219     };
28220     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
28221     static const DWORD hs_code[] =
28222     {
28223         0x43425844, 0x23a919a7, 0xf5fdd1b4, 0x4f5a835f, 0xca389c71, 0x00000001, 0x00000464, 0x00000004,
28224         0x00000030, 0x0000008c, 0x00000124, 0x00000200, 0x4e475349, 0x00000054, 0x00000002, 0x00000008,
28225         0x00000038, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, 0x00000000,
28226         0x00000000, 0x00000003, 0x00000001, 0x00000101, 0x49534f50, 0x4e4f4954, 0x46455200, 0x4655425f,
28227         0x5f524546, 0x41544144, 0xababab00, 0x4e47534f, 0x00000090, 0x00000004, 0x00000008, 0x00000068,
28228         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x00000071, 0x00000000, 0x00000000,
28229         0x00000003, 0x00000001, 0x00000e01, 0x00000081, 0x00000000, 0x00000000, 0x00000001, 0x00000002,
28230         0x00000e01, 0x00000089, 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000d02, 0x49534f50,
28231         0x4e4f4954, 0x46455200, 0x4655425f, 0x5f524546, 0x41544144, 0x49525000, 0x44495f4d, 0x5f504300,
28232         0xab004449, 0x47534350, 0x000000d4, 0x00000006, 0x00000008, 0x00000098, 0x00000000, 0x0000000d,
28233         0x00000003, 0x00000000, 0x00000e01, 0x000000a6, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
28234         0x00000d02, 0x00000098, 0x00000001, 0x0000000d, 0x00000003, 0x00000001, 0x00000e01, 0x000000b2,
28235         0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000d02, 0x00000098, 0x00000002, 0x0000000d,
28236         0x00000003, 0x00000002, 0x00000e01, 0x000000c0, 0x00000000, 0x0000000e, 0x00000003, 0x00000003,
28237         0x00000e01, 0x545f5653, 0x46737365, 0x6f746361, 0x55420072, 0x52454646, 0x5441445f, 0x41500041,
28238         0x5f484354, 0x4d495250, 0x0044495f, 0x495f5653, 0x6469736e, 0x73655465, 0x63614673, 0x00726f74,
28239         0x58454853, 0x0000025c, 0x00030050, 0x00000097, 0x01000071, 0x01001893, 0x01001894, 0x01001095,
28240         0x01000896, 0x01001897, 0x0100086a, 0x030000a1, 0x00107000, 0x00000000, 0x01000072, 0x0200005f,
28241         0x00016000, 0x0200005f, 0x0000b000, 0x0400005f, 0x002010f2, 0x00000003, 0x00000000, 0x0400005f,
28242         0x00201012, 0x00000003, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x03000065, 0x00102012,
28243         0x00000001, 0x03000065, 0x00102012, 0x00000002, 0x03000065, 0x00102022, 0x00000002, 0x02000068,
28244         0x00000001, 0x04000036, 0x00100012, 0x00000000, 0x00016001, 0x07000036, 0x001020f2, 0x00000000,
28245         0x00a01e46, 0x0010000a, 0x00000000, 0x00000000, 0x07000036, 0x00102012, 0x00000001, 0x00a0100a,
28246         0x0010000a, 0x00000000, 0x00000001, 0x04000036, 0x00102012, 0x00000002, 0x0000b001, 0x04000036,
28247         0x00102022, 0x00000002, 0x00016001, 0x0100003e, 0x01000073, 0x02000099, 0x00000003, 0x0200005f,
28248         0x00017000, 0x04000067, 0x00102012, 0x00000000, 0x00000011, 0x04000067, 0x00102012, 0x00000001,
28249         0x00000012, 0x04000067, 0x00102012, 0x00000002, 0x00000013, 0x02000068, 0x00000001, 0x0400005b,
28250         0x00102012, 0x00000000, 0x00000003, 0x04000036, 0x00100012, 0x00000000, 0x0001700a, 0x06000036,
28251         0x00902012, 0x0010000a, 0x00000000, 0x00004001, 0x40800000, 0x0100003e, 0x01000073, 0x04000067,
28252         0x00102012, 0x00000003, 0x00000014, 0x05000036, 0x00102012, 0x00000003, 0x00004001, 0x40800000,
28253         0x0100003e, 0x01000073, 0x0200005f, 0x0000b000, 0x03000065, 0x00102022, 0x00000000, 0x02000068,
28254         0x00000001, 0x06000029, 0x00100012, 0x00000000, 0x0000b001, 0x00004001, 0x00000002, 0x890000a5,
28255         0x800002c2, 0x00199983, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00107006, 0x00000000,
28256         0x05000056, 0x00102022, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e, 0x01000073, 0x0200005f,
28257         0x0000b000, 0x03000065, 0x00102022, 0x00000001, 0x04000036, 0x00102022, 0x00000001, 0x0000b001,
28258         0x0100003e,
28259     };
28260     static const D3D12_SHADER_BYTECODE hs = {hs_code, sizeof(hs_code)};
28261     static const DWORD ds_code[] =
28262     {
28263         0x43425844, 0x4b659bb4, 0x3eb61f16, 0xaa8397b6, 0xd60e8c43, 0x00000001, 0x000005ec, 0x00000004,
28264         0x00000030, 0x000000c8, 0x000001a4, 0x000001f8, 0x4e475349, 0x00000090, 0x00000004, 0x00000008,
28265         0x00000068, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000071, 0x00000000,
28266         0x00000000, 0x00000003, 0x00000001, 0x00000101, 0x00000081, 0x00000000, 0x00000000, 0x00000001,
28267         0x00000002, 0x00000101, 0x00000089, 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000202,
28268         0x49534f50, 0x4e4f4954, 0x46455200, 0x4655425f, 0x5f524546, 0x41544144, 0x49525000, 0x44495f4d,
28269         0x5f504300, 0xab004449, 0x47534350, 0x000000d4, 0x00000006, 0x00000008, 0x00000098, 0x00000000,
28270         0x0000000d, 0x00000003, 0x00000000, 0x00000001, 0x000000a6, 0x00000000, 0x00000000, 0x00000003,
28271         0x00000000, 0x00000202, 0x00000098, 0x00000001, 0x0000000d, 0x00000003, 0x00000001, 0x00000001,
28272         0x000000b2, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000202, 0x00000098, 0x00000002,
28273         0x0000000d, 0x00000003, 0x00000002, 0x00000001, 0x000000c0, 0x00000000, 0x0000000e, 0x00000003,
28274         0x00000003, 0x00000001, 0x545f5653, 0x46737365, 0x6f746361, 0x55420072, 0x52454646, 0x5441445f,
28275         0x41500041, 0x5f484354, 0x4d495250, 0x0044495f, 0x495f5653, 0x6469736e, 0x73655465, 0x63614673,
28276         0x00726f74, 0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001,
28277         0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
28278         0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x58454853, 0x000003ec,
28279         0x00040050, 0x000000fb, 0x01001893, 0x01001095, 0x0100086a, 0x0300005f, 0x0011b022, 0x00000000,
28280         0x0300005f, 0x0011b022, 0x00000001, 0x0200005f, 0x0001c072, 0x0400005f, 0x002190f2, 0x00000003,
28281         0x00000000, 0x0400005f, 0x00219012, 0x00000003, 0x00000001, 0x0400005f, 0x00219012, 0x00000003,
28282         0x00000002, 0x0400005f, 0x00219022, 0x00000003, 0x00000002, 0x04000067, 0x001020f2, 0x00000000,
28283         0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x02000068, 0x00000002, 0x07000038, 0x001000f2,
28284         0x00000000, 0x0001c556, 0x00219e46, 0x00000001, 0x00000000, 0x09000032, 0x001000f2, 0x00000000,
28285         0x0001c006, 0x00219e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000, 0x09000032, 0x001000f2,
28286         0x00000000, 0x0001caa6, 0x00219e46, 0x00000002, 0x00000000, 0x00100e46, 0x00000000, 0x05000036,
28287         0x00100012, 0x00000001, 0x00004001, 0x00000000, 0x01000030, 0x07000050, 0x00100022, 0x00000001,
28288         0x0010000a, 0x00000001, 0x00004001, 0x00000003, 0x03040003, 0x0010001a, 0x00000001, 0x09000039,
28289         0x00100022, 0x00000001, 0x0011b01a, 0x00000000, 0x00a1900a, 0x0010000a, 0x00000001, 0x00000001,
28290         0x0304001f, 0x0010001a, 0x00000001, 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
28291         0x08000036, 0x00102092, 0x00000001, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,
28292         0x09000038, 0x00102022, 0x00000001, 0x00004001, 0x3b808081, 0x00a1900a, 0x0010000a, 0x00000001,
28293         0x00000001, 0x07000038, 0x00102042, 0x00000001, 0x0011b01a, 0x00000000, 0x00004001, 0x3b808081,
28294         0x0100003e, 0x01000015, 0x0700001e, 0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x00004001,
28295         0x00000001, 0x01000016, 0x05000036, 0x00100012, 0x00000001, 0x00004001, 0x00000000, 0x01000030,
28296         0x07000050, 0x00100022, 0x00000001, 0x0010000a, 0x00000001, 0x00004001, 0x00000003, 0x03040003,
28297         0x0010001a, 0x00000001, 0x09000027, 0x00100022, 0x00000001, 0x0011b01a, 0x00000001, 0x00a1900a,
28298         0x0010000a, 0x00000001, 0x00000002, 0x0304001f, 0x0010001a, 0x00000001, 0x05000036, 0x001020f2,
28299         0x00000000, 0x00100e46, 0x00000000, 0x08000036, 0x001020f2, 0x00000001, 0x00004002, 0x3f800000,
28300         0x00000000, 0x3f800000, 0x3f800000, 0x0100003e, 0x01000015, 0x0700001e, 0x00100012, 0x00000001,
28301         0x0010000a, 0x00000001, 0x00004001, 0x00000001, 0x01000016, 0x08000027, 0x00100012, 0x00000001,
28302         0x00004001, 0x00000000, 0x0021901a, 0x00000000, 0x00000002, 0x08000027, 0x00100022, 0x00000001,
28303         0x00004001, 0x00000001, 0x0021901a, 0x00000001, 0x00000002, 0x0700003c, 0x00100012, 0x00000001,
28304         0x0010001a, 0x00000001, 0x0010000a, 0x00000001, 0x08000027, 0x00100022, 0x00000001, 0x00004001,
28305         0x00000002, 0x0021901a, 0x00000002, 0x00000002, 0x0700003c, 0x00100012, 0x00000001, 0x0010001a,
28306         0x00000001, 0x0010000a, 0x00000001, 0x0304001f, 0x0010000a, 0x00000001, 0x05000036, 0x001020f2,
28307         0x00000000, 0x00100e46, 0x00000000, 0x08000036, 0x001020f2, 0x00000001, 0x00004002, 0x3f800000,
28308         0x3f800000, 0x00000000, 0x3f800000, 0x0100003e, 0x01000015, 0x05000036, 0x001020f2, 0x00000000,
28309         0x00100e46, 0x00000000, 0x08000036, 0x001020f2, 0x00000001, 0x00004002, 0x00000000, 0x3f800000,
28310         0x00000000, 0x3f800000, 0x0100003e,
28311     };
28312     static const D3D12_SHADER_BYTECODE ds = {ds_code, sizeof(ds_code)};
28313     static const DWORD ps_code[] =
28314     {
28315 #if 0
28316         float4 main(in float4 p : SV_Position, in float4 color : COLOR) : SV_Target
28317         {
28318             return color;
28319         }
28320 #endif
28321         0x43425844, 0xbd83f517, 0x8974e87a, 0xaf402223, 0xaec7f351, 0x00000001, 0x000000f8, 0x00000003,
28322         0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
28323         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000,
28324         0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x4f4c4f43, 0xabab0052,
28325         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
28326         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000003c, 0x00000050,
28327         0x0000000f, 0x0100086a, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
28328         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e,
28329     };
28330     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
28331     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
28332     {
28333         {"POSITION",        0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0,  0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
28334         {"REF_BUFFER_DATA", 0, DXGI_FORMAT_R32_FLOAT,          0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
28335     };
28336     static const struct
28337     {
28338         struct vec4 position;
28339         float ref_buffer_data;
28340     }
28341     vertices[] =
28342     {
28343         {{-1.0f, -1.0f, 0.0f, 1.0f}, 1.0f},
28344         {{-1.0f,  1.0f, 0.0f, 1.0f}, 1.0f},
28345         {{ 1.0f, -1.0f, 0.0f, 1.0f}, 1.0f},
28346 
28347         {{-1.0f,  1.0f, 0.0f, 1.0f}, 2.0f},
28348         {{ 1.0f,  1.0f, 0.0f, 1.0f}, 2.0f},
28349         {{ 1.0f, -1.0f, 0.0f, 1.0f}, 2.0f},
28350     };
28351     static const uint32_t buffer_data[] = {1, 2};
28352 
28353     memset(&desc, 0, sizeof(desc));
28354     desc.no_root_signature = true;
28355     if (!init_test_context(&context, &desc))
28356         return;
28357     command_list = context.list;
28358     queue = context.queue;
28359 
28360     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
28361     root_parameters[0].Descriptor.ShaderRegister = 0;
28362     root_parameters[0].Descriptor.RegisterSpace = 0;
28363     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_HULL;
28364     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
28365     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
28366     root_signature_desc.pParameters = root_parameters;
28367     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
28368     hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
28369     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
28370 
28371     input_layout.pInputElementDescs = layout_desc;
28372     input_layout.NumElements = ARRAY_SIZE(layout_desc);
28373     init_pipeline_state_desc(&pso_desc, context.root_signature,
28374             context.render_target_desc.Format, NULL, NULL, &input_layout);
28375     pso_desc.VS = vs;
28376     pso_desc.HS = hs;
28377     pso_desc.DS = ds;
28378     pso_desc.PS = ps;
28379     pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH;
28380     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
28381             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
28382     ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
28383 
28384     vb = create_upload_buffer(context.device, sizeof(vertices), vertices);
28385     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
28386     vbv.StrideInBytes = sizeof(*vertices);
28387     vbv.SizeInBytes = sizeof(vertices);
28388 
28389     raw_buffer = create_upload_buffer(context.device, sizeof(buffer_data), buffer_data);
28390 
28391     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
28392 
28393     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
28394     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
28395     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
28396     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST);
28397     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
28398     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
28399     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
28400     ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(command_list,
28401             0, ID3D12Resource_GetGPUVirtualAddress(raw_buffer));
28402     ID3D12GraphicsCommandList_DrawInstanced(command_list, 6, 1, 0, 0);
28403 
28404     transition_resource_state(command_list, context.render_target,
28405             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
28406     bug_if(is_nvidia_device(context.device))
28407     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
28408 
28409     ID3D12Resource_Release(vb);
28410     ID3D12Resource_Release(raw_buffer);
28411     destroy_test_context(&context);
28412 }
28413 
test_render_a8(void)28414 static void test_render_a8(void)
28415 {
28416     static const float black[] = {0.0f, 0.0f, 0.0f, 0.0f};
28417     ID3D12GraphicsCommandList *command_list;
28418     struct test_context_desc desc;
28419     struct test_context context;
28420     ID3D12CommandQueue *queue;
28421 
28422     static const DWORD ps_code[] =
28423     {
28424 #if 0
28425         void main(out float4 target : SV_Target)
28426         {
28427             target = float4(0.0f, 0.25f, 0.5f, 1.0f);
28428         }
28429 #endif
28430         0x43425844, 0x2f09e5ff, 0xaa135d5e, 0x7860f4b5, 0x5c7b8cbc, 0x00000001, 0x000000b4, 0x00000003,
28431         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
28432         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
28433         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000003c, 0x00000050, 0x0000000f,
28434         0x0100086a, 0x03000065, 0x001020f2, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002,
28435         0x00000000, 0x3e800000, 0x3f000000, 0x3f800000, 0x0100003e,
28436     };
28437     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
28438 
28439     memset(&desc, 0, sizeof(desc));
28440     desc.rt_format = DXGI_FORMAT_A8_UNORM;
28441     desc.ps = &ps;
28442     if (!init_test_context(&context, &desc))
28443         return;
28444     command_list = context.list;
28445     queue = context.queue;
28446 
28447     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, black, 0, NULL);
28448 
28449     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
28450     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
28451     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
28452     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
28453     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
28454     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
28455     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
28456 
28457     transition_resource_state(command_list, context.render_target,
28458             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
28459 
28460     check_sub_resource_uint8(context.render_target, 0, queue, command_list, 0xff, 0);
28461 
28462     destroy_test_context(&context);
28463 }
28464 
test_cpu_descriptors_lifetime(void)28465 static void test_cpu_descriptors_lifetime(void)
28466 {
28467     static const float blue[] = {0.0f, 0.0f, 1.0f, 1.0f};
28468     static const float red[] = {1.0f, 0.0f, 0.0f, 1.0f};
28469     ID3D12Resource *red_resource, *blue_resource;
28470     ID3D12GraphicsCommandList *command_list;
28471     D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle;
28472     D3D12_HEAP_PROPERTIES heap_properties;
28473     D3D12_RESOURCE_DESC resource_desc;
28474     ID3D12DescriptorHeap *rtv_heap;
28475     D3D12_CLEAR_VALUE clear_value;
28476     struct test_context context;
28477     ID3D12CommandQueue *queue;
28478     ID3D12Device *device;
28479     HRESULT hr;
28480 
28481     if (!init_test_context(&context, NULL))
28482         return;
28483     device = context.device;
28484     command_list = context.list;
28485     queue = context.queue;
28486 
28487     rtv_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1);
28488     rtv_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rtv_heap);
28489 
28490     memset(&heap_properties, 0, sizeof(heap_properties));
28491     heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
28492     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
28493     resource_desc.Alignment = 0;
28494     resource_desc.Width = 32;
28495     resource_desc.Height = 32;
28496     resource_desc.DepthOrArraySize = 1;
28497     resource_desc.MipLevels = 1;
28498     resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
28499     resource_desc.SampleDesc.Count = 1;
28500     resource_desc.SampleDesc.Quality = 0;
28501     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
28502     resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
28503     clear_value.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
28504     clear_value.Color[0] = 1.0f;
28505     clear_value.Color[1] = 0.0f;
28506     clear_value.Color[2] = 0.0f;
28507     clear_value.Color[3] = 1.0f;
28508     hr = ID3D12Device_CreateCommittedResource(device,
28509             &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
28510             D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
28511             &IID_ID3D12Resource, (void **)&red_resource);
28512     ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
28513     clear_value.Color[0] = 0.0f;
28514     clear_value.Color[1] = 0.0f;
28515     clear_value.Color[2] = 1.0f;
28516     clear_value.Color[3] = 1.0f;
28517     hr = ID3D12Device_CreateCommittedResource(device,
28518             &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
28519             D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
28520             &IID_ID3D12Resource, (void **)&blue_resource);
28521     ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
28522 
28523     ID3D12Device_CreateRenderTargetView(device, red_resource, NULL, rtv_handle);
28524     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, red, 0, NULL);
28525     /* Destroy the previous RTV and create a new one in its place. */
28526     ID3D12Device_CreateRenderTargetView(device, blue_resource, NULL, rtv_handle);
28527     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, blue, 0, NULL);
28528 
28529     /* Destroy the CPU descriptor heap. */
28530     ID3D12DescriptorHeap_Release(rtv_heap);
28531 
28532     transition_resource_state(command_list, red_resource,
28533             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
28534     transition_resource_state(command_list, blue_resource,
28535             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
28536     check_sub_resource_uint(red_resource, 0, queue, command_list, 0xff0000ff, 0);
28537     reset_command_list(command_list, context.allocator);
28538     check_sub_resource_uint(blue_resource, 0, queue, command_list, 0xffff0000, 0);
28539 
28540     rtv_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1);
28541     rtv_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rtv_heap);
28542 
28543     /* Try again with OMSetRenderTargets(). */
28544     reset_command_list(command_list, context.allocator);
28545     transition_resource_state(command_list, red_resource,
28546             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
28547     transition_resource_state(command_list, blue_resource,
28548             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
28549 
28550     ID3D12Device_CreateRenderTargetView(device, red_resource, NULL, rtv_handle);
28551     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, red, 0, NULL);
28552 
28553     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &rtv_handle, false, NULL);
28554     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
28555     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
28556     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
28557     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
28558     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
28559     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
28560 
28561     /* Destroy the previous RTV and create a new one in its place. */
28562     ID3D12Device_CreateRenderTargetView(device, blue_resource, NULL, rtv_handle);
28563     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, rtv_handle, blue, 0, NULL);
28564 
28565     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &rtv_handle, false, NULL);
28566     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
28567     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
28568     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
28569     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
28570     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
28571     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
28572 
28573     /* Destroy the previous RTV and create a new one in its place. */
28574     ID3D12Device_CreateRenderTargetView(device, red_resource, NULL, rtv_handle);
28575 
28576     /* Destroy the CPU descriptor heap. */
28577     ID3D12DescriptorHeap_Release(rtv_heap);
28578 
28579     transition_resource_state(command_list, red_resource,
28580             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
28581     transition_resource_state(command_list, blue_resource,
28582             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
28583     check_sub_resource_uint(red_resource, 0, queue, command_list, 0xff00ff00, 0);
28584     reset_command_list(command_list, context.allocator);
28585     check_sub_resource_uint(blue_resource, 0, queue, command_list, 0xff00ff00, 0);
28586 
28587     ID3D12Resource_Release(blue_resource);
28588     ID3D12Resource_Release(red_resource);
28589     destroy_test_context(&context);
28590 }
28591 
check_clip_distance(struct test_context * context,ID3D12PipelineState * pso,D3D12_VERTEX_BUFFER_VIEW vbv[2],ID3D12Resource * vb,ID3D12Resource * vs_cb,ID3D12Resource * gs_cb)28592 static void check_clip_distance(struct test_context *context,
28593         ID3D12PipelineState *pso, D3D12_VERTEX_BUFFER_VIEW vbv[2], ID3D12Resource *vb,
28594         ID3D12Resource *vs_cb, ID3D12Resource *gs_cb)
28595 {
28596     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
28597     struct vertex
28598     {
28599         float clip_distance0;
28600         float clip_distance1;
28601     };
28602 
28603     ID3D12GraphicsCommandList *command_list = context->list;
28604     ID3D12CommandQueue *queue = context->queue;
28605     struct resource_readback rb;
28606     struct vertex vertices[4];
28607     unsigned int i;
28608     D3D12_BOX box;
28609 
28610     for (i = 0; i < ARRAY_SIZE(vertices); ++i)
28611         vertices[i].clip_distance0 = 1.0f;
28612     update_buffer_data(vb, 0, sizeof(vertices), vertices);
28613     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context->rtv, false, NULL);
28614     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context->root_signature);
28615     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
28616             ID3D12Resource_GetGPUVirtualAddress(vs_cb));
28617     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2,
28618             ID3D12Resource_GetGPUVirtualAddress(gs_cb));
28619     ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
28620     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
28621     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context->viewport);
28622     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context->scissor_rect);
28623     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 2, vbv);
28624     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context->rtv, white, 0, NULL);
28625     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
28626     transition_resource_state(command_list, context->render_target,
28627             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
28628     check_sub_resource_uint(context->render_target, 0, queue, command_list, 0xff00ff00, 0);
28629 
28630     reset_command_list(command_list, context->allocator);
28631     transition_resource_state(command_list, context->render_target,
28632             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
28633 
28634     for (i = 0; i < ARRAY_SIZE(vertices); ++i)
28635         vertices[i].clip_distance0 = 0.0f;
28636     update_buffer_data(vb, 0, sizeof(vertices), vertices);
28637     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context->rtv, false, NULL);
28638     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context->root_signature);
28639     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
28640             ID3D12Resource_GetGPUVirtualAddress(vs_cb));
28641     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2,
28642             ID3D12Resource_GetGPUVirtualAddress(gs_cb));
28643     ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
28644     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
28645     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context->viewport);
28646     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context->scissor_rect);
28647     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 2, vbv);
28648     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context->rtv, white, 0, NULL);
28649     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
28650     transition_resource_state(command_list, context->render_target,
28651             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
28652     check_sub_resource_uint(context->render_target, 0, queue, command_list, 0xff00ff00, 0);
28653 
28654     reset_command_list(command_list, context->allocator);
28655     transition_resource_state(command_list, context->render_target,
28656             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
28657 
28658     for (i = 0; i < ARRAY_SIZE(vertices); ++i)
28659         vertices[i].clip_distance0 = -1.0f;
28660     update_buffer_data(vb, 0, sizeof(vertices), vertices);
28661     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context->rtv, false, NULL);
28662     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context->root_signature);
28663     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
28664             ID3D12Resource_GetGPUVirtualAddress(vs_cb));
28665     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2,
28666             ID3D12Resource_GetGPUVirtualAddress(gs_cb));
28667     ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
28668     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
28669     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context->viewport);
28670     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context->scissor_rect);
28671     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 2, vbv);
28672     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context->rtv, white, 0, NULL);
28673     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
28674     transition_resource_state(command_list, context->render_target,
28675             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
28676     check_sub_resource_uint(context->render_target, 0, queue, command_list, 0xffffffff, 0);
28677 
28678     reset_command_list(command_list, context->allocator);
28679     transition_resource_state(command_list, context->render_target,
28680             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
28681 
28682     for (i = 0; i < ARRAY_SIZE(vertices); ++i)
28683         vertices[i].clip_distance0 = i < 2 ? 1.0f : -1.0f;
28684     update_buffer_data(vb, 0, sizeof(vertices), vertices);
28685     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context->rtv, false, NULL);
28686     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context->root_signature);
28687     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
28688             ID3D12Resource_GetGPUVirtualAddress(vs_cb));
28689     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2,
28690             ID3D12Resource_GetGPUVirtualAddress(gs_cb));
28691     ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
28692     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
28693     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context->viewport);
28694     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context->scissor_rect);
28695     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 2, vbv);
28696     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context->rtv, white, 0, NULL);
28697     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
28698     transition_resource_state(command_list, context->render_target,
28699             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
28700     get_texture_readback_with_command_list(context->render_target, 0, &rb, queue, command_list);
28701     set_box(&box, 0, 0, 0, 320, 480, 1);
28702     check_readback_data_uint(&rb, &box, 0xff00ff00, 1);
28703     set_box(&box, 320, 0, 0, 320, 480, 1);
28704     check_readback_data_uint(&rb, &box, 0xffffffff, 1);
28705     release_resource_readback(&rb);
28706 
28707     reset_command_list(command_list, context->allocator);
28708     transition_resource_state(command_list, context->render_target,
28709             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
28710 
28711     for (i = 0; i < ARRAY_SIZE(vertices); ++i)
28712         vertices[i].clip_distance0 = i % 2 ? 1.0f : -1.0f;
28713     update_buffer_data(vb, 0, sizeof(vertices), vertices);
28714     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context->rtv, false, NULL);
28715     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context->root_signature);
28716     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
28717             ID3D12Resource_GetGPUVirtualAddress(vs_cb));
28718     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2,
28719             ID3D12Resource_GetGPUVirtualAddress(gs_cb));
28720     ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
28721     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
28722     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context->viewport);
28723     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context->scissor_rect);
28724     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 2, vbv);
28725     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context->rtv, white, 0, NULL);
28726     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
28727     transition_resource_state(command_list, context->render_target,
28728             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
28729     get_texture_readback_with_command_list(context->render_target, 0, &rb, queue, command_list);
28730     set_box(&box, 0, 0, 0, 640, 240, 1);
28731     check_readback_data_uint(&rb, &box, 0xff00ff00, 0);
28732     set_box(&box, 0, 240, 0, 640, 240, 1);
28733     check_readback_data_uint(&rb, &box, 0xffffffff, 0);
28734     release_resource_readback(&rb);
28735 
28736     reset_command_list(command_list, context->allocator);
28737     transition_resource_state(command_list, context->render_target,
28738             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
28739 }
28740 
test_clip_distance(void)28741 static void test_clip_distance(void)
28742 {
28743     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
28744     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
28745     D3D12_ROOT_PARAMETER root_parameters[3];
28746     ID3D12GraphicsCommandList *command_list;
28747     ID3D12Resource *vs_cb, *gs_cb, *vb[2];
28748     D3D12_INPUT_LAYOUT_DESC input_layout;
28749     D3D12_VERTEX_BUFFER_VIEW vbv[2];
28750     struct test_context_desc desc;
28751     struct resource_readback rb;
28752     struct test_context context;
28753     ID3D12CommandQueue *queue;
28754     ID3D12PipelineState *pso;
28755     ID3D12Device *device;
28756     unsigned int i;
28757     D3D12_BOX box;
28758     HRESULT hr;
28759 
28760     static const DWORD vs_code[] =
28761     {
28762 #if 0
28763         bool use_constant;
28764         float clip_distance;
28765 
28766         struct input
28767         {
28768             float4 position : POSITION;
28769             float distance0 : CLIP_DISTANCE0;
28770             float distance1 : CLIP_DISTANCE1;
28771         };
28772 
28773         struct vertex
28774         {
28775             float4 position : SV_POSITION;
28776             float user_clip : CLIP_DISTANCE;
28777             float clip : SV_ClipDistance;
28778         };
28779 
28780         void main(input vin, out vertex vertex)
28781         {
28782             vertex.position = vin.position;
28783             vertex.user_clip = vin.distance0;
28784             vertex.clip = vin.distance0;
28785             if (use_constant)
28786                 vertex.clip = clip_distance;
28787         }
28788 #endif
28789         0x43425844, 0x09dfef58, 0x88570f2e, 0x1ebcf953, 0x9f97e22a, 0x00000001, 0x000001dc, 0x00000003,
28790         0x0000002c, 0x0000009c, 0x00000120, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
28791         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000059, 0x00000000, 0x00000000,
28792         0x00000003, 0x00000001, 0x00000101, 0x00000059, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
28793         0x00000001, 0x49534f50, 0x4e4f4954, 0x494c4300, 0x49445f50, 0x4e415453, 0xab004543, 0x4e47534f,
28794         0x0000007c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, 0x00000003, 0x00000000,
28795         0x0000000f, 0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000e01, 0x0000006a,
28796         0x00000000, 0x00000002, 0x00000003, 0x00000002, 0x00000e01, 0x505f5653, 0x5449534f, 0x004e4f49,
28797         0x50494c43, 0x5349445f, 0x434e4154, 0x56530045, 0x696c435f, 0x73694470, 0x636e6174, 0xabab0065,
28798         0x52444853, 0x000000b4, 0x00010040, 0x0000002d, 0x04000059, 0x00208e46, 0x00000000, 0x00000001,
28799         0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x00101012, 0x00000001, 0x04000067, 0x001020f2,
28800         0x00000000, 0x00000001, 0x03000065, 0x00102012, 0x00000001, 0x04000067, 0x00102012, 0x00000002,
28801         0x00000002, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x00102012,
28802         0x00000001, 0x0010100a, 0x00000001, 0x0b000037, 0x00102012, 0x00000002, 0x0020800a, 0x00000000,
28803         0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x0010100a, 0x00000001, 0x0100003e,
28804     };
28805     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
28806     static const DWORD vs_multiple_code[] =
28807     {
28808 #if 0
28809         bool use_constant;
28810         float clip_distance0;
28811         float clip_distance1;
28812 
28813         struct input
28814         {
28815             float4 position : POSITION;
28816             float distance0 : CLIP_DISTANCE0;
28817             float distance1 : CLIP_DISTANCE1;
28818         };
28819 
28820         struct vertex
28821         {
28822             float4 position : SV_POSITION;
28823             float user_clip : CLIP_DISTANCE;
28824             float2 clip : SV_ClipDistance;
28825         };
28826 
28827         void main(input vin, out vertex vertex)
28828         {
28829             vertex.position = vin.position;
28830             vertex.user_clip = vin.distance0;
28831             vertex.clip.x = vin.distance0;
28832             if (use_constant)
28833                 vertex.clip.x = clip_distance0;
28834             vertex.clip.y = vin.distance1;
28835             if (use_constant)
28836                 vertex.clip.y = clip_distance1;
28837         }
28838 #endif
28839         0x43425844, 0xef5cc236, 0xe2fbfa69, 0x560b6591, 0x23037999, 0x00000001, 0x00000214, 0x00000003,
28840         0x0000002c, 0x0000009c, 0x00000120, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
28841         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000059, 0x00000000, 0x00000000,
28842         0x00000003, 0x00000001, 0x00000101, 0x00000059, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
28843         0x00000101, 0x49534f50, 0x4e4f4954, 0x494c4300, 0x49445f50, 0x4e415453, 0xab004543, 0x4e47534f,
28844         0x0000007c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, 0x00000003, 0x00000000,
28845         0x0000000f, 0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000e01, 0x0000006a,
28846         0x00000000, 0x00000002, 0x00000003, 0x00000002, 0x00000c03, 0x505f5653, 0x5449534f, 0x004e4f49,
28847         0x50494c43, 0x5349445f, 0x434e4154, 0x56530045, 0x696c435f, 0x73694470, 0x636e6174, 0xabab0065,
28848         0x52444853, 0x000000ec, 0x00010040, 0x0000003b, 0x04000059, 0x00208e46, 0x00000000, 0x00000001,
28849         0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x00101012, 0x00000001, 0x0300005f, 0x00101012,
28850         0x00000002, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102012, 0x00000001,
28851         0x04000067, 0x00102032, 0x00000002, 0x00000002, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46,
28852         0x00000000, 0x05000036, 0x00102012, 0x00000001, 0x0010100a, 0x00000001, 0x0b000037, 0x00102012,
28853         0x00000002, 0x0020800a, 0x00000000, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x0010100a,
28854         0x00000001, 0x0b000037, 0x00102022, 0x00000002, 0x0020800a, 0x00000000, 0x00000000, 0x0020802a,
28855         0x00000000, 0x00000000, 0x0010100a, 0x00000002, 0x0100003e,
28856     };
28857     static const D3D12_SHADER_BYTECODE vs_multiple = {vs_multiple_code, sizeof(vs_multiple_code)};
28858     static const DWORD gs_code[] =
28859     {
28860 #if 0
28861         bool use_constant;
28862         float clip_distance;
28863 
28864         struct vertex
28865         {
28866             float4 position : SV_POSITION;
28867             float user_clip : CLIP_DISTANCE;
28868             float clip : SV_ClipDistance;
28869         };
28870 
28871         [maxvertexcount(3)]
28872         void main(triangle vertex input[3], inout TriangleStream<vertex> output)
28873         {
28874             vertex o;
28875             o = input[0];
28876             o.clip = input[0].user_clip;
28877             if (use_constant)
28878                 o.clip = clip_distance;
28879             output.Append(o);
28880             o = input[1];
28881             o.clip = input[1].user_clip;
28882             if (use_constant)
28883                 o.clip = clip_distance;
28884             output.Append(o);
28885             o = input[2];
28886             o.clip = input[2].user_clip;
28887             if (use_constant)
28888                 o.clip = clip_distance;
28889             output.Append(o);
28890         }
28891 #endif
28892         0x43425844, 0x9b0823e9, 0xab3ed100, 0xba0ff618, 0x1bbd1cb8, 0x00000001, 0x00000338, 0x00000003,
28893         0x0000002c, 0x000000b0, 0x00000134, 0x4e475349, 0x0000007c, 0x00000003, 0x00000008, 0x00000050,
28894         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x00000f0f, 0x0000005c, 0x00000000, 0x00000000,
28895         0x00000003, 0x00000001, 0x00000101, 0x0000006a, 0x00000000, 0x00000002, 0x00000003, 0x00000002,
28896         0x00000001, 0x505f5653, 0x5449534f, 0x004e4f49, 0x50494c43, 0x5349445f, 0x434e4154, 0x56530045,
28897         0x696c435f, 0x73694470, 0x636e6174, 0xabab0065, 0x4e47534f, 0x0000007c, 0x00000003, 0x00000008,
28898         0x00000050, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
28899         0x00000000, 0x00000003, 0x00000001, 0x00000e01, 0x0000006a, 0x00000000, 0x00000002, 0x00000003,
28900         0x00000002, 0x00000e01, 0x505f5653, 0x5449534f, 0x004e4f49, 0x50494c43, 0x5349445f, 0x434e4154,
28901         0x56530045, 0x696c435f, 0x73694470, 0x636e6174, 0xabab0065, 0x52444853, 0x000001fc, 0x00020040,
28902         0x0000007f, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x05000061, 0x002010f2, 0x00000003,
28903         0x00000000, 0x00000001, 0x0400005f, 0x00201012, 0x00000003, 0x00000001, 0x0400005f, 0x00201012,
28904         0x00000003, 0x00000002, 0x02000068, 0x00000001, 0x0100185d, 0x0100285c, 0x04000067, 0x001020f2,
28905         0x00000000, 0x00000001, 0x03000065, 0x00102012, 0x00000001, 0x04000067, 0x00102012, 0x00000002,
28906         0x00000002, 0x0200005e, 0x00000003, 0x06000036, 0x001020f2, 0x00000000, 0x00201e46, 0x00000000,
28907         0x00000000, 0x06000036, 0x00102012, 0x00000001, 0x0020100a, 0x00000000, 0x00000001, 0x0c000037,
28908         0x00100012, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0020801a, 0x00000000, 0x00000000,
28909         0x0020100a, 0x00000000, 0x00000001, 0x05000036, 0x00102012, 0x00000002, 0x0010000a, 0x00000000,
28910         0x01000013, 0x06000036, 0x001020f2, 0x00000000, 0x00201e46, 0x00000001, 0x00000000, 0x06000036,
28911         0x00102012, 0x00000001, 0x0020100a, 0x00000001, 0x00000001, 0x0c000037, 0x00100012, 0x00000000,
28912         0x0020800a, 0x00000000, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x0020100a, 0x00000001,
28913         0x00000001, 0x05000036, 0x00102012, 0x00000002, 0x0010000a, 0x00000000, 0x01000013, 0x06000036,
28914         0x001020f2, 0x00000000, 0x00201e46, 0x00000002, 0x00000000, 0x06000036, 0x00102012, 0x00000001,
28915         0x0020100a, 0x00000002, 0x00000001, 0x0c000037, 0x00100012, 0x00000000, 0x0020800a, 0x00000000,
28916         0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x0020100a, 0x00000002, 0x00000001, 0x05000036,
28917         0x00102012, 0x00000002, 0x0010000a, 0x00000000, 0x01000013, 0x0100003e,
28918     };
28919     static const D3D12_SHADER_BYTECODE gs = {gs_code, sizeof(gs_code)};
28920     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
28921     {
28922         {"POSITION",      0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
28923         {"CLIP_DISTANCE", 0, DXGI_FORMAT_R32_FLOAT,    1, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
28924         {"CLIP_DISTANCE", 1, DXGI_FORMAT_R32_FLOAT,    1, 4, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
28925     };
28926     static const struct vec4 quad[] =
28927     {
28928         {-1.0f, -1.0f},
28929         {-1.0f,  1.0f},
28930         { 1.0f, -1.0f},
28931         { 1.0f,  1.0f},
28932     };
28933     struct
28934     {
28935         float clip_distance0;
28936         float clip_distance1;
28937     }
28938     vertices[] =
28939     {
28940         {1.0f, 1.0f},
28941         {1.0f, 1.0f},
28942         {1.0f, 1.0f},
28943         {1.0f, 1.0f},
28944     };
28945     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
28946     struct
28947     {
28948         bool use_constant;
28949         float clip_distance0;
28950         float clip_distance1;
28951         float padding;
28952     } cb_data;
28953 
28954     memset(&desc, 0, sizeof(desc));
28955     desc.rt_width = 640;
28956     desc.rt_height = 480;
28957     desc.no_root_signature = true;
28958     if (!init_test_context(&context, &desc))
28959         return;
28960     device = context.device;
28961     command_list = context.list;
28962     queue = context.queue;
28963 
28964     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
28965     root_parameters[0].Descriptor.ShaderRegister = 0;
28966     root_parameters[0].Descriptor.RegisterSpace = 0;
28967     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
28968     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
28969     root_parameters[1].Descriptor.ShaderRegister = 1;
28970     root_parameters[1].Descriptor.RegisterSpace = 0;
28971     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
28972     root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
28973     root_parameters[2].Descriptor.ShaderRegister = 0;
28974     root_parameters[2].Descriptor.RegisterSpace = 0;
28975     root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_GEOMETRY;
28976     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
28977     root_signature_desc.pParameters = root_parameters;
28978     root_signature_desc.NumStaticSamplers = 0;
28979     root_signature_desc.pStaticSamplers = NULL;
28980     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
28981     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
28982     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
28983 
28984     input_layout.pInputElementDescs = layout_desc;
28985     input_layout.NumElements = ARRAY_SIZE(layout_desc);
28986 
28987     init_pipeline_state_desc(&pso_desc, context.root_signature,
28988             context.render_target_desc.Format, &vs, NULL, &input_layout);
28989     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
28990             &IID_ID3D12PipelineState, (void **)&pso);
28991     ok(hr == S_OK, "Failed to create pipeline state, hr %#x.\n", hr);
28992 
28993     vb[0] = create_upload_buffer(device, sizeof(quad), quad);
28994     vbv[0].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb[0]);
28995     vbv[0].StrideInBytes = sizeof(*quad);
28996     vbv[0].SizeInBytes = sizeof(quad);
28997 
28998     vb[1] = create_upload_buffer(device, sizeof(vertices), vertices);
28999     vbv[1].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb[1]);
29000     vbv[1].StrideInBytes = sizeof(*vertices);
29001     vbv[1].SizeInBytes = sizeof(vertices);
29002 
29003     memset(&cb_data, 0, sizeof(cb_data));
29004     vs_cb = create_upload_buffer(device, sizeof(cb_data), &cb_data);
29005     gs_cb = create_upload_buffer(device, sizeof(cb_data), &cb_data);
29006 
29007     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
29008     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
29009     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
29010             ID3D12Resource_GetGPUVirtualAddress(vs_cb));
29011     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2,
29012             ID3D12Resource_GetGPUVirtualAddress(gs_cb));
29013     ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
29014     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
29015     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
29016     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
29017     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
29018 
29019     /* vertex shader */
29020     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
29021     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
29022     transition_resource_state(command_list, context.render_target,
29023             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
29024     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
29025 
29026     reset_command_list(command_list, context.allocator);
29027     transition_resource_state(command_list, context.render_target,
29028             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
29029     check_clip_distance(&context, pso, vbv, vb[1], vs_cb, gs_cb);
29030 
29031     cb_data.use_constant = true;
29032     cb_data.clip_distance0 = -1.0f;
29033     update_buffer_data(vs_cb, 0, sizeof(cb_data), &cb_data);
29034 
29035     ID3D12PipelineState_Release(pso);
29036 
29037     /* geometry shader */
29038     pso_desc.GS = gs;
29039     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
29040             &IID_ID3D12PipelineState, (void **)&pso);
29041     ok(hr == S_OK, "Failed to create pipeline state, hr %#x.\n", hr);
29042 
29043     check_clip_distance(&context, pso, vbv, vb[1], vs_cb, gs_cb);
29044 
29045     cb_data.use_constant = true;
29046     cb_data.clip_distance0 = 1.0f;
29047     update_buffer_data(gs_cb, 0, sizeof(cb_data), &cb_data);
29048     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
29049     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
29050     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
29051             ID3D12Resource_GetGPUVirtualAddress(vs_cb));
29052     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2,
29053             ID3D12Resource_GetGPUVirtualAddress(gs_cb));
29054     ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
29055     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
29056     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
29057     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
29058     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
29059     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
29060     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
29061     transition_resource_state(command_list, context.render_target,
29062             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
29063     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
29064 
29065     ID3D12PipelineState_Release(pso);
29066     reset_command_list(command_list, context.allocator);
29067     transition_resource_state(command_list, context.render_target,
29068             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
29069 
29070     /* multiple clip distances */
29071     pso_desc.VS = vs_multiple;
29072     memset(&pso_desc.GS, 0, sizeof(pso_desc.GS));
29073     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
29074             &IID_ID3D12PipelineState, (void **)&pso);
29075     ok(hr == S_OK, "Failed to create pipeline state, hr %#x.\n", hr);
29076 
29077     cb_data.use_constant = false;
29078     update_buffer_data(vs_cb, 0, sizeof(cb_data), &cb_data);
29079 
29080     for (i = 0; i < ARRAY_SIZE(vertices); ++i)
29081         vertices[i].clip_distance0 = 1.0f;
29082     update_buffer_data(vb[1], 0, sizeof(vertices), vertices);
29083     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
29084     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
29085     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
29086             ID3D12Resource_GetGPUVirtualAddress(vs_cb));
29087     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2,
29088             ID3D12Resource_GetGPUVirtualAddress(gs_cb));
29089     ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
29090     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
29091     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
29092     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
29093     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
29094     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
29095     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
29096     transition_resource_state(command_list, context.render_target,
29097             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
29098     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
29099 
29100     reset_command_list(command_list, context.allocator);
29101     transition_resource_state(command_list, context.render_target,
29102             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
29103 
29104     for (i = 0; i < ARRAY_SIZE(vertices); ++i)
29105     {
29106         vertices[i].clip_distance0 = i < 2 ? 1.0f : -1.0f;
29107         vertices[i].clip_distance1 = i % 2 ? 1.0f : -1.0f;
29108     }
29109     update_buffer_data(vb[1], 0, sizeof(vertices), vertices);
29110     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
29111     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
29112     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
29113             ID3D12Resource_GetGPUVirtualAddress(vs_cb));
29114     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2,
29115             ID3D12Resource_GetGPUVirtualAddress(gs_cb));
29116     ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
29117     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
29118     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
29119     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
29120     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
29121     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
29122     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
29123     transition_resource_state(command_list, context.render_target,
29124             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
29125 
29126     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
29127     set_box(&box, 0, 0, 0, 320, 240, 1);
29128     check_readback_data_uint(&rb, &box, 0xff00ff00, 1);
29129     set_box(&box, 0, 240, 0, 320, 480, 1);
29130     check_readback_data_uint(&rb, &box, 0xffffffff, 1);
29131     set_box(&box, 320, 0, 0, 640, 480, 1);
29132     check_readback_data_uint(&rb, &box, 0xffffffff, 1);
29133     release_resource_readback(&rb);
29134 
29135     reset_command_list(command_list, context.allocator);
29136     transition_resource_state(command_list, context.render_target,
29137             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
29138 
29139     cb_data.use_constant = true;
29140     cb_data.clip_distance0 = 0.0f;
29141     cb_data.clip_distance1 = 0.0f;
29142     update_buffer_data(vs_cb, 0, sizeof(cb_data), &cb_data);
29143     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
29144     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
29145     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
29146             ID3D12Resource_GetGPUVirtualAddress(vs_cb));
29147     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 2,
29148             ID3D12Resource_GetGPUVirtualAddress(gs_cb));
29149     ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
29150     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
29151     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
29152     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
29153     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
29154     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
29155     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
29156     transition_resource_state(command_list, context.render_target,
29157             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
29158     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
29159 
29160     ID3D12PipelineState_Release(pso);
29161     for (i = 0; i < ARRAY_SIZE(vb); ++i)
29162         ID3D12Resource_Release(vb[i]);
29163     ID3D12Resource_Release(vs_cb);
29164     ID3D12Resource_Release(gs_cb);
29165     destroy_test_context(&context);
29166 }
29167 
test_combined_clip_and_cull_distances(void)29168 static void test_combined_clip_and_cull_distances(void)
29169 {
29170     ID3D12GraphicsCommandList *command_list;
29171     D3D12_INPUT_LAYOUT_DESC input_layout;
29172     D3D12_VERTEX_BUFFER_VIEW vbv[2];
29173     struct test_context_desc desc;
29174     struct test_context context;
29175     struct resource_readback rb;
29176     ID3D12CommandQueue *queue;
29177     ID3D12Resource *vb[2];
29178     ID3D12Device *device;
29179     unsigned int i, j, k;
29180 
29181     static const DWORD vs_code[] =
29182     {
29183 #if 0
29184         struct input
29185         {
29186             float4 position : POSITION;
29187             float clip0 : CLIP_DISTANCE0;
29188             float clip1 : CLIP_DISTANCE1;
29189             float clip2 : CLIP_DISTANCE2;
29190             float clip3 : CLIP_DISTANCE3;
29191             float cull0 : CULL_DISTANCE0;
29192             float cull1 : CULL_DISTANCE1;
29193             float cull2 : CULL_DISTANCE2;
29194             float cull3 : CULL_DISTANCE3;
29195         };
29196 
29197         struct vertex
29198         {
29199             float4 position : SV_Position;
29200             float3 clip0 : SV_ClipDistance1;
29201             float3 cull0 : SV_CullDistance1;
29202             float clip1 : SV_ClipDistance2;
29203             float cull1 : SV_CullDistance2;
29204         };
29205 
29206         void main(input vin, out vertex vertex)
29207         {
29208             vertex.position = vin.position;
29209             vertex.clip0 = float3(vin.clip0, vin.clip1, vin.clip2);
29210             vertex.cull0 = float3(vin.cull0, vin.cull1, vin.cull2);
29211             vertex.clip1 = vin.clip3;
29212             vertex.cull1 = vin.cull3;
29213         }
29214 #endif
29215         0x43425844, 0xa24fb3ea, 0x92e2c2b0, 0xb599b1b9, 0xd671f830, 0x00000001, 0x00000374, 0x00000003,
29216         0x0000002c, 0x0000013c, 0x000001f0, 0x4e475349, 0x00000108, 0x00000009, 0x00000008, 0x000000e0,
29217         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x000000e9, 0x00000000, 0x00000000,
29218         0x00000003, 0x00000001, 0x00000101, 0x000000e9, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
29219         0x00000101, 0x000000e9, 0x00000002, 0x00000000, 0x00000003, 0x00000003, 0x00000101, 0x000000e9,
29220         0x00000003, 0x00000000, 0x00000003, 0x00000004, 0x00000101, 0x000000f7, 0x00000000, 0x00000000,
29221         0x00000003, 0x00000005, 0x00000101, 0x000000f7, 0x00000001, 0x00000000, 0x00000003, 0x00000006,
29222         0x00000101, 0x000000f7, 0x00000002, 0x00000000, 0x00000003, 0x00000007, 0x00000101, 0x000000f7,
29223         0x00000003, 0x00000000, 0x00000003, 0x00000008, 0x00000101, 0x49534f50, 0x4e4f4954, 0x494c4300,
29224         0x49445f50, 0x4e415453, 0x43004543, 0x5f4c4c55, 0x54534944, 0x45434e41, 0xababab00, 0x4e47534f,
29225         0x000000ac, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000001, 0x00000003, 0x00000000,
29226         0x0000000f, 0x0000008c, 0x00000000, 0x00000002, 0x00000003, 0x00000001, 0x00000807, 0x0000008c,
29227         0x00000001, 0x00000002, 0x00000003, 0x00000001, 0x00000708, 0x0000009c, 0x00000000, 0x00000003,
29228         0x00000003, 0x00000002, 0x00000807, 0x0000009c, 0x00000001, 0x00000003, 0x00000003, 0x00000002,
29229         0x00000708, 0x505f5653, 0x7469736f, 0x006e6f69, 0x435f5653, 0x4470696c, 0x61747369, 0x0065636e,
29230         0x435f5653, 0x446c6c75, 0x61747369, 0x0065636e, 0x52444853, 0x0000017c, 0x00010040, 0x0000005f,
29231         0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x00101012, 0x00000001, 0x0300005f, 0x00101012,
29232         0x00000002, 0x0300005f, 0x00101012, 0x00000003, 0x0300005f, 0x00101012, 0x00000004, 0x0300005f,
29233         0x00101012, 0x00000005, 0x0300005f, 0x00101012, 0x00000006, 0x0300005f, 0x00101012, 0x00000007,
29234         0x0300005f, 0x00101012, 0x00000008, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x04000067,
29235         0x00102072, 0x00000001, 0x00000002, 0x04000067, 0x00102082, 0x00000001, 0x00000002, 0x04000067,
29236         0x00102072, 0x00000002, 0x00000003, 0x04000067, 0x00102082, 0x00000002, 0x00000003, 0x05000036,
29237         0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x00102012, 0x00000001, 0x0010100a,
29238         0x00000001, 0x05000036, 0x00102022, 0x00000001, 0x0010100a, 0x00000002, 0x05000036, 0x00102042,
29239         0x00000001, 0x0010100a, 0x00000003, 0x05000036, 0x00102082, 0x00000001, 0x0010100a, 0x00000004,
29240         0x05000036, 0x00102012, 0x00000002, 0x0010100a, 0x00000005, 0x05000036, 0x00102022, 0x00000002,
29241         0x0010100a, 0x00000006, 0x05000036, 0x00102042, 0x00000002, 0x0010100a, 0x00000007, 0x05000036,
29242         0x00102082, 0x00000002, 0x0010100a, 0x00000008, 0x0100003e,
29243     };
29244     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
29245     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
29246     {
29247         {"POSITION",      0, DXGI_FORMAT_R32G32_FLOAT, 0,  0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
29248         {"CLIP_DISTANCE", 0, DXGI_FORMAT_R32_FLOAT,    1,  0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
29249         {"CLIP_DISTANCE", 1, DXGI_FORMAT_R32_FLOAT,    1,  4, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
29250         {"CLIP_DISTANCE", 2, DXGI_FORMAT_R32_FLOAT,    1,  8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
29251         {"CLIP_DISTANCE", 3, DXGI_FORMAT_R32_FLOAT,    1, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
29252         {"CULL_DISTANCE", 0, DXGI_FORMAT_R32_FLOAT,    1, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
29253         {"CULL_DISTANCE", 1, DXGI_FORMAT_R32_FLOAT,    1, 20, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
29254         {"CULL_DISTANCE", 2, DXGI_FORMAT_R32_FLOAT,    1, 24, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
29255         {"CULL_DISTANCE", 3, DXGI_FORMAT_R32_FLOAT,    1, 28, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
29256     };
29257     static const struct vec4 quad[] =
29258     {
29259         {-1.0f, -1.0f},
29260         {-1.0f,  1.0f},
29261         { 1.0f, -1.0f},
29262         { 1.0f,  1.0f},
29263     };
29264     struct
29265     {
29266         float clip_distance[4];
29267         float cull_distance[4];
29268     }
29269     vertices[4] =
29270     {
29271         {{1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
29272         {{1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
29273         {{1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
29274         {{1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
29275     };
29276     static const struct test
29277     {
29278         float vertices[4];
29279         bool triangle_visible[2];
29280     }
29281     cull_distance_tests[] =
29282     {
29283         {{-1.0f,  1.0f,  1.0f,  1.0f}, {true, true}},
29284         {{ 1.0f, -1.0f,  1.0f,  1.0f}, {true, true}},
29285         {{ 1.0f,  1.0f,  1.0f, -1.0f}, {true, true}},
29286         {{-1.0f, -1.0f,  1.0f,  1.0f}, {true, true}},
29287         {{-1.0f,  1.0f, -1.0f,  1.0f}, {true, true}},
29288         {{-1.0f,  1.0f,  1.0f, -1.0f}, {true, true}},
29289         {{ 1.0f, -1.0f, -1.0f,  1.0f}, {true, true}},
29290         {{ 1.0f, -1.0f,  1.0f, -1.0f}, {true, true}},
29291         {{ 1.0f,  1.0f, -1.0f, -1.0f}, {true, true}},
29292 
29293         {{-1.0f, -1.0f, -1.0f,  1.0f}, {false, true}},
29294         {{-1.0f, -1.0f,  1.0f, -1.0f}, {true,  true}},
29295         {{-1.0f, -1.0f,  1.0f, -1.0f}, {true,  true}},
29296         {{-1.0f,  1.0f, -1.0f, -1.0f}, {true,  true}},
29297         {{ 1.0f, -1.0f, -1.0f, -1.0f}, {true,  false}},
29298 
29299         {{-1.0f, -1.0f, -1.0f, -1.0f}, {false, false}},
29300     };
29301     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
29302 
29303     memset(&desc, 0, sizeof(desc));
29304     desc.rt_width = 640;
29305     desc.rt_height = 480;
29306     desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
29307     desc.no_pipeline = true;
29308     if (!init_test_context(&context, &desc))
29309         return;
29310     device = context.device;
29311     command_list = context.list;
29312     queue = context.queue;
29313 
29314     input_layout.pInputElementDescs = layout_desc;
29315     input_layout.NumElements = ARRAY_SIZE(layout_desc);
29316 
29317     context.pipeline_state = create_pipeline_state(device, context.root_signature,
29318             context.render_target_desc.Format, &vs, NULL, &input_layout);
29319 
29320     vb[0] = create_upload_buffer(device, sizeof(quad), quad);
29321     vbv[0].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb[0]);
29322     vbv[0].StrideInBytes = sizeof(*quad);
29323     vbv[0].SizeInBytes = sizeof(quad);
29324 
29325     vb[1] = create_upload_buffer(device, sizeof(vertices), vertices);
29326     vbv[1].BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb[1]);
29327     vbv[1].StrideInBytes = sizeof(*vertices);
29328     vbv[1].SizeInBytes = sizeof(vertices);
29329 
29330     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
29331     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
29332     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
29333     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
29334     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
29335     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
29336     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
29337     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
29338     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
29339     transition_resource_state(command_list, context.render_target,
29340             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
29341     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
29342 
29343     reset_command_list(command_list, context.allocator);
29344     transition_resource_state(command_list, context.render_target,
29345             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
29346 
29347     for (i = 0; i < ARRAY_SIZE(vertices->cull_distance); ++i)
29348     {
29349         for (j = 0; j < ARRAY_SIZE(cull_distance_tests); ++j)
29350         {
29351             const struct test *test = &cull_distance_tests[j];
29352             unsigned int expected_color[ARRAY_SIZE(test->triangle_visible)];
29353             unsigned int color;
29354 
29355             for (k = 0; k < ARRAY_SIZE(vertices); ++k)
29356                 vertices[k].cull_distance[i] = test->vertices[k];
29357             update_buffer_data(vb[1], 0, sizeof(vertices), vertices);
29358 
29359             ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
29360             ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
29361             ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
29362             ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
29363             ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
29364             ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
29365             ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
29366             ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
29367             ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
29368             transition_resource_state(command_list, context.render_target,
29369                     D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
29370 
29371             for (k = 0; k < ARRAY_SIZE(expected_color); ++k)
29372                 expected_color[k] = test->triangle_visible[k] ? 0xff00ff00 : 0xffffffff;
29373 
29374             if (expected_color[0] == expected_color[1])
29375             {
29376                 check_sub_resource_uint(context.render_target, 0, queue, command_list, expected_color[0], 0);
29377             }
29378             else
29379             {
29380                 get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
29381                 color = get_readback_uint(&rb, 160, 240, 0);
29382                 ok(color == expected_color[0], "Got unexpected color 0x%08x.\n", color);
29383                 color = get_readback_uint(&rb, 480, 240, 0);
29384                 ok(color == expected_color[1], "Got unexpected color 0x%08x.\n", color);
29385                 release_resource_readback(&rb);
29386             }
29387 
29388             reset_command_list(command_list, context.allocator);
29389             transition_resource_state(command_list, context.render_target,
29390                     D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
29391         }
29392 
29393         for (j = 0; j < ARRAY_SIZE(vertices); ++j)
29394             vertices[j].cull_distance[i] = 1.0f;
29395     }
29396 
29397     for (i = 0; i < ARRAY_SIZE(vertices->clip_distance); ++i)
29398     {
29399         for (j = 0; j < ARRAY_SIZE(vertices); ++j)
29400             vertices[j].clip_distance[i] = -1.0f;
29401         update_buffer_data(vb[1], 0, sizeof(vertices), vertices);
29402 
29403         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
29404         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
29405         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
29406         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
29407         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
29408         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
29409         ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
29410         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
29411         ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
29412         transition_resource_state(command_list, context.render_target,
29413                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
29414 
29415         check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xffffffff, 0);
29416 
29417         reset_command_list(command_list, context.allocator);
29418         transition_resource_state(command_list, context.render_target,
29419                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
29420 
29421         for (j = 0; j < ARRAY_SIZE(vertices); ++j)
29422             vertices[j].clip_distance[i] = 1.0f;
29423     }
29424 
29425     memset(vertices, 0, sizeof(vertices));
29426     update_buffer_data(vb[1], 0, sizeof(vertices), vertices);
29427     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
29428     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
29429     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
29430     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
29431     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
29432     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
29433     ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, ARRAY_SIZE(vbv), vbv);
29434     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
29435     ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
29436     transition_resource_state(command_list, context.render_target,
29437             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
29438     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
29439 
29440     for (i = 0; i < ARRAY_SIZE(vb); ++i)
29441         ID3D12Resource_Release(vb[i]);
29442     destroy_test_context(&context);
29443 }
29444 
test_resource_allocation_info(void)29445 static void test_resource_allocation_info(void)
29446 {
29447     D3D12_RESOURCE_ALLOCATION_INFO info;
29448     D3D12_RESOURCE_DESC desc;
29449     ID3D12Device *device;
29450     unsigned int i, j;
29451     ULONG refcount;
29452 
29453     static const unsigned int alignments[] =
29454     {
29455         0,
29456         D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT,
29457         D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,
29458         D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT,
29459     };
29460     static const unsigned int buffer_sizes[] =
29461     {
29462         1,
29463         16,
29464         256,
29465         1024,
29466         D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT,
29467         D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT + 1,
29468         D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,
29469         D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT + 1,
29470         D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT,
29471         D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT + 1,
29472     };
29473     static const struct
29474     {
29475         unsigned int width;
29476         unsigned int height;
29477         unsigned int array_size;
29478         unsigned int miplevels;
29479         DXGI_FORMAT format;
29480     }
29481     texture_tests[] =
29482     {
29483         { 4,  4, 1, 1, DXGI_FORMAT_R8_UINT},
29484         { 8,  8, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM},
29485         {16, 16, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM},
29486         {16, 16, 1024, 1, DXGI_FORMAT_R8G8B8A8_UNORM},
29487         {256, 512, 1, 10, DXGI_FORMAT_BC1_UNORM},
29488         {256, 512, 64, 1, DXGI_FORMAT_BC1_UNORM},
29489 
29490         {1024, 1024, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM},
29491         {1024, 1024, 1, 2, DXGI_FORMAT_R8G8B8A8_UNORM},
29492         {1024, 1024, 1, 3, DXGI_FORMAT_R8G8B8A8_UNORM},
29493         {1024, 1024, 1, 0, DXGI_FORMAT_R8G8B8A8_UNORM},
29494         {260, 512, 1, 1, DXGI_FORMAT_BC1_UNORM},
29495     };
29496 
29497     if (!(device = create_device()))
29498     {
29499         skip("Failed to create device.\n");
29500         return;
29501     }
29502 
29503     desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
29504     desc.Alignment = 0;
29505     desc.Width = 32;
29506     desc.Height = 1;
29507     desc.DepthOrArraySize = 1;
29508     desc.MipLevels = 1;
29509     desc.Format = DXGI_FORMAT_UNKNOWN;
29510     desc.SampleDesc.Count = 1;
29511     desc.SampleDesc.Quality = 0;
29512     desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
29513     desc.Flags = 0;
29514 
29515     for (i = 0; i < ARRAY_SIZE(alignments); ++i)
29516     {
29517         for (j = 0; j < ARRAY_SIZE(buffer_sizes); ++j)
29518         {
29519             desc.Alignment = alignments[i];
29520             desc.Width = buffer_sizes[j];
29521             info = ID3D12Device_GetResourceAllocationInfo(device, 0, 1, &desc);
29522             if (!desc.Alignment || desc.Alignment == D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT)
29523             {
29524                 check_alignment(info.SizeInBytes, info.Alignment);
29525             }
29526             else
29527             {
29528                 ok(info.SizeInBytes == ~(uint64_t)0,
29529                         "Got unexpected size %"PRIu64".\n", info.SizeInBytes);
29530                 ok(info.Alignment == D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,
29531                         "Got unexpected alignment %"PRIu64".\n", info.Alignment);
29532             }
29533         }
29534     }
29535 
29536     desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
29537     desc.SampleDesc.Count = 1;
29538     desc.SampleDesc.Quality = 0;
29539     desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
29540     desc.Flags = 0;
29541 
29542     for (i = 0; i < ARRAY_SIZE(texture_tests); ++i)
29543     {
29544         desc.Width = texture_tests[i].width;
29545         desc.Height = texture_tests[i].height;
29546         desc.DepthOrArraySize = texture_tests[i].array_size;
29547         desc.MipLevels = texture_tests[i].miplevels;
29548         desc.Format = texture_tests[i].format;
29549 
29550         desc.Alignment = 0;
29551         info = ID3D12Device_GetResourceAllocationInfo(device, 0, 1, &desc);
29552         ok(info.Alignment >= D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,
29553                 "Got unexpected alignment %"PRIu64".\n", info.Alignment);
29554         check_alignment(info.SizeInBytes, info.Alignment);
29555 
29556         desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
29557         info = ID3D12Device_GetResourceAllocationInfo(device, 0, 1, &desc);
29558         ok(info.Alignment >= D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,
29559                 "Got unexpected alignment %"PRIu64".\n", info.Alignment);
29560         check_alignment(info.SizeInBytes, info.Alignment);
29561 
29562         desc.Alignment = D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT;
29563         info = ID3D12Device_GetResourceAllocationInfo(device, 0, 1, &desc);
29564         ok(info.Alignment >= D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT,
29565                 "Got unexpected alignment %"PRIu64".\n", info.Alignment);
29566         if (i < 6)
29567         {
29568             check_alignment(info.SizeInBytes, info.Alignment);
29569         }
29570         else
29571         {
29572             ok(info.SizeInBytes == ~(uint64_t)0,
29573                     "Got unexpected size %"PRIu64".\n", info.SizeInBytes);
29574             ok(info.Alignment >= D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,
29575                     "Got unexpected alignment %"PRIu64".\n", info.Alignment);
29576         }
29577     }
29578 
29579     refcount = ID3D12Device_Release(device);
29580     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
29581 }
29582 
test_suballocate_small_textures(void)29583 static void test_suballocate_small_textures(void)
29584 {
29585     D3D12_GPU_VIRTUAL_ADDRESS gpu_address;
29586     D3D12_RESOURCE_ALLOCATION_INFO info;
29587     D3D12_RESOURCE_DESC resource_desc;
29588     ID3D12Resource *textures[10];
29589     D3D12_HEAP_DESC heap_desc;
29590     ID3D12Device *device;
29591     ID3D12Heap *heap;
29592     unsigned int i;
29593     ULONG refcount;
29594     HRESULT hr;
29595 
29596     if (!(device = create_device()))
29597     {
29598         skip("Failed to create device.\n");
29599         return;
29600     }
29601 
29602     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
29603     resource_desc.Alignment = 0;
29604     resource_desc.Width = 32;
29605     resource_desc.Height = 32;
29606     resource_desc.DepthOrArraySize = 1;
29607     resource_desc.MipLevels = 1;
29608     resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
29609     resource_desc.SampleDesc.Count = 1;
29610     resource_desc.SampleDesc.Quality = 0;
29611     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
29612     resource_desc.Flags = 0;
29613 
29614     resource_desc.Alignment = D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT;
29615 
29616     info = ID3D12Device_GetResourceAllocationInfo(device, 0, 1, &resource_desc);
29617     trace("Size %"PRIu64", alignment %"PRIu64".\n", info.SizeInBytes, info.Alignment);
29618     check_alignment(info.SizeInBytes, info.Alignment);
29619     if (info.Alignment != D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT)
29620     {
29621         resource_desc.Alignment = 0;
29622         info = ID3D12Device_GetResourceAllocationInfo(device, 0, 1, &resource_desc);
29623         trace("Size %"PRIu64", alignment %"PRIu64".\n", info.SizeInBytes, info.Alignment);
29624         check_alignment(info.SizeInBytes, info.Alignment);
29625     }
29626 
29627     ok(info.Alignment >= D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT, "Got alignment %"PRIu64".\n", info.Alignment);
29628 
29629     heap_desc.SizeInBytes = ARRAY_SIZE(textures) * info.SizeInBytes;
29630     memset(&heap_desc.Properties, 0, sizeof(heap_desc.Properties));
29631     heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT;
29632     heap_desc.Alignment = 0;
29633     heap_desc.Flags = D3D12_HEAP_FLAG_DENY_BUFFERS | D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES;
29634     hr = ID3D12Device_CreateHeap(device, &heap_desc, &IID_ID3D12Heap, (void **)&heap);
29635     ok(hr == S_OK, "Failed to create heap, hr %#x.\n", hr);
29636 
29637     for (i = 0; i < ARRAY_SIZE(textures); ++i)
29638     {
29639         hr = ID3D12Device_CreatePlacedResource(device, heap, i * info.SizeInBytes,
29640                 &resource_desc, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
29641                 NULL, &IID_ID3D12Resource, (void **)&textures[i]);
29642         ok(hr == S_OK, "Failed to create placed resource %u, hr %#x.\n", i, hr);
29643 
29644         check_interface(textures[i], &IID_ID3D12Object, true);
29645         check_interface(textures[i], &IID_ID3D12DeviceChild, true);
29646         check_interface(textures[i], &IID_ID3D12Pageable, true);
29647         check_interface(textures[i], &IID_ID3D12Resource, true);
29648 
29649         gpu_address = ID3D12Resource_GetGPUVirtualAddress(textures[i]);
29650         ok(!gpu_address, "Got unexpected GPU virtual address %#"PRIx64".\n", gpu_address);
29651     }
29652 
29653     refcount = get_refcount(heap);
29654     ok(refcount == 1, "Got unexpected refcount %u.\n", (unsigned int)refcount);
29655 
29656     for (i = 0; i < ARRAY_SIZE(textures); ++i)
29657     {
29658         refcount = ID3D12Resource_Release(textures[i]);
29659         ok(!refcount, "ID3D12Resource has %u references left.\n", (unsigned int)refcount);
29660     }
29661 
29662     refcount = ID3D12Heap_Release(heap);
29663     ok(!refcount, "ID3D12Heap has %u references left.\n", (unsigned int)refcount);
29664     refcount = ID3D12Device_Release(device);
29665     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
29666 }
29667 
test_command_list_initial_pipeline_state(void)29668 static void test_command_list_initial_pipeline_state(void)
29669 {
29670     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
29671     ID3D12GraphicsCommandList *command_list;
29672     ID3D12PipelineState *pipeline_state;
29673     ID3D12CommandAllocator *allocator;
29674     struct test_context context;
29675     ID3D12CommandQueue *queue;
29676     HRESULT hr;
29677 
29678     static const DWORD ps_code[] =
29679     {
29680 #if 0
29681         void main(out float4 target : SV_Target)
29682         {
29683             target = float4(0.0f, 0.25f, 0.5f, 1.0f);
29684         }
29685 #endif
29686         0x43425844, 0x2f09e5ff, 0xaa135d5e, 0x7860f4b5, 0x5c7b8cbc, 0x00000001, 0x000000b4, 0x00000003,
29687         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
29688         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
29689         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000003c, 0x00000050, 0x0000000f,
29690         0x0100086a, 0x03000065, 0x001020f2, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002,
29691         0x00000000, 0x3e800000, 0x3f000000, 0x3f800000, 0x0100003e,
29692     };
29693     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
29694 
29695     if (!init_test_context(&context, NULL))
29696         return;
29697     queue = context.queue;
29698 
29699     pipeline_state = create_pipeline_state(context.device,
29700             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
29701 
29702     hr = ID3D12Device_CreateCommandAllocator(context.device, D3D12_COMMAND_LIST_TYPE_DIRECT,
29703             &IID_ID3D12CommandAllocator, (void **)&allocator);
29704     ok(hr == S_OK, "Failed to create command allocator, hr %#x.\n", hr);
29705     hr = ID3D12Device_CreateCommandList(context.device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
29706             allocator, pipeline_state, &IID_ID3D12GraphicsCommandList, (void **)&command_list);
29707     ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
29708 
29709     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
29710     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
29711     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
29712     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
29713     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
29714     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
29715     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
29716     transition_resource_state(command_list, context.render_target,
29717             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
29718     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff804000, 1);
29719 
29720     hr = ID3D12CommandAllocator_Reset(allocator);
29721     ok(hr == S_OK, "Failed to reset command allocator, hr %#x.\n", hr);
29722     hr = ID3D12GraphicsCommandList_Reset(command_list, allocator, context.pipeline_state);
29723     ok(hr == S_OK, "Failed to reset command list, hr %#x.\n", hr);
29724     transition_resource_state(command_list, context.render_target,
29725             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
29726 
29727     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
29728     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
29729     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
29730     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
29731     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
29732     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
29733     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
29734     transition_resource_state(command_list, context.render_target,
29735             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
29736     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
29737 
29738     ID3D12CommandAllocator_Release(allocator);
29739     ID3D12GraphicsCommandList_Release(command_list);
29740     ID3D12PipelineState_Release(pipeline_state);
29741     destroy_test_context(&context);
29742 }
29743 
test_blend_factor(void)29744 static void test_blend_factor(void)
29745 {
29746     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
29747     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
29748     ID3D12GraphicsCommandList *command_list;
29749     struct test_context_desc desc;
29750     struct test_context context;
29751     ID3D12CommandQueue *queue;
29752     unsigned int i;
29753     HRESULT hr;
29754 
29755     static const struct
29756     {
29757         float blend_factor[4];
29758         unsigned int expected_color;
29759     }
29760     tests[] =
29761     {
29762         {{0.0f, 0.0f, 0.0f, 0.0f}, 0xffffffff},
29763         {{0.0f, 1.0f, 0.0f, 1.0f}, 0xffffffff},
29764         {{0.5f, 0.5f, 0.5f, 0.5f}, 0xff80ff80},
29765         {{1.0f, 1.0f, 1.0f, 1.0f}, 0xff00ff00},
29766     };
29767 
29768     memset(&desc, 0, sizeof(desc));
29769     desc.no_pipeline = true;
29770     if (!init_test_context(&context, &desc))
29771         return;
29772     command_list = context.list;
29773     queue = context.queue;
29774 
29775     init_pipeline_state_desc(&pso_desc, context.root_signature,
29776             context.render_target_desc.Format, NULL, NULL, NULL);
29777     pso_desc.BlendState.RenderTarget[0].BlendEnable = true;
29778     pso_desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_BLEND_FACTOR;
29779     pso_desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_BLEND_FACTOR;
29780     pso_desc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
29781     pso_desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_BLEND_FACTOR;
29782     pso_desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_BLEND_FACTOR;
29783     pso_desc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
29784     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
29785             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
29786     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
29787 
29788     for (i = 0; i < ARRAY_SIZE(tests); ++i)
29789     {
29790         vkd3d_test_set_context("Test %u", i);
29791 
29792         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
29793         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
29794         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
29795         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
29796         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
29797         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
29798         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
29799         ID3D12GraphicsCommandList_OMSetBlendFactor(command_list, tests[i].blend_factor);
29800         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
29801         transition_resource_state(command_list, context.render_target,
29802                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
29803         check_sub_resource_uint(context.render_target, 0, queue, command_list, tests[i].expected_color, 1);
29804 
29805         reset_command_list(command_list, context.allocator);
29806         transition_resource_state(command_list, context.render_target,
29807                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
29808     }
29809     vkd3d_test_set_context(NULL);
29810 
29811     destroy_test_context(&context);
29812 }
29813 
test_dual_source_blending(void)29814 static void test_dual_source_blending(void)
29815 {
29816     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
29817     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
29818     ID3D12GraphicsCommandList *command_list;
29819     struct test_context_desc desc;
29820     struct test_context context;
29821     ID3D12CommandQueue *queue;
29822     unsigned int i;
29823     HRESULT hr;
29824 
29825     static const DWORD ps_code[] =
29826     {
29827 #if 0
29828         float4 c0;
29829         float4 c1;
29830 
29831         void main(out float4 o0 : SV_Target0, out float4 o1 : SV_Target1)
29832         {
29833             o0 = c0;
29834             o1 = c1;
29835         }
29836 #endif
29837         0x43425844, 0x823a4ecf, 0xd409abf6, 0xe76697ab, 0x9b53c9a5, 0x00000001, 0x000000f8, 0x00000003,
29838         0x0000002c, 0x0000003c, 0x00000088, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
29839         0x00000044, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
29840         0x0000000f, 0x00000038, 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x545f5653,
29841         0x65677261, 0xabab0074, 0x58454853, 0x00000068, 0x00000050, 0x0000001a, 0x0100086a, 0x04000059,
29842         0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000, 0x03000065, 0x001020f2,
29843         0x00000001, 0x06000036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x06000036,
29844         0x001020f2, 0x00000001, 0x00208e46, 0x00000000, 0x00000001, 0x0100003e,
29845     };
29846     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
29847     static const struct
29848     {
29849         struct
29850         {
29851             struct vec4 c0;
29852             struct vec4 c1;
29853         } constants;
29854         unsigned int expected_color;
29855     }
29856     tests[] =
29857     {
29858         {{{0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}}, 0x00000000},
29859         {{{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}}, 0xff0000ff},
29860         {{{1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 0.0f}}, 0xff0000ff},
29861         {{{1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 1.0f, 0.0f}}, 0xffffffff},
29862     };
29863 
29864     memset(&desc, 0, sizeof(desc));
29865     desc.no_root_signature = true;
29866     if (!init_test_context(&context, &desc))
29867         return;
29868     command_list = context.list;
29869     queue = context.queue;
29870 
29871     context.root_signature = create_32bit_constants_root_signature(context.device,
29872             0, sizeof(tests->constants) / sizeof(uint32_t), D3D12_SHADER_VISIBILITY_PIXEL);
29873 
29874     init_pipeline_state_desc(&pso_desc, context.root_signature,
29875             context.render_target_desc.Format, NULL, &ps, NULL);
29876     pso_desc.BlendState.RenderTarget[0].BlendEnable = true;
29877     pso_desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_COLOR;
29878     pso_desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_SRC1_COLOR;
29879     pso_desc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
29880     pso_desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA;
29881     pso_desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_SRC1_ALPHA;
29882     pso_desc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
29883     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
29884             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
29885     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
29886 
29887     for (i = 0; i < ARRAY_SIZE(tests); ++i)
29888     {
29889         vkd3d_test_set_context("Test %u", i);
29890 
29891         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
29892         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
29893         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
29894         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
29895         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
29896         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
29897         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
29898         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 8, &tests[i].constants, 0);
29899         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
29900         transition_resource_state(command_list, context.render_target,
29901                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
29902         check_sub_resource_uint(context.render_target, 0, queue, command_list, tests[i].expected_color, 1);
29903 
29904         reset_command_list(command_list, context.allocator);
29905         transition_resource_state(command_list, context.render_target,
29906                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
29907     }
29908     vkd3d_test_set_context(NULL);
29909 
29910     ID3D12PipelineState_Release(context.pipeline_state);
29911     pso_desc.BlendState.IndependentBlendEnable = true;
29912     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
29913             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
29914     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
29915     ID3D12PipelineState_Release(context.pipeline_state);
29916     context.pipeline_state = NULL;
29917 
29918     pso_desc.BlendState.RenderTarget[1] = pso_desc.BlendState.RenderTarget[0];
29919     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
29920             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
29921     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
29922 
29923     pso_desc.BlendState.RenderTarget[1].DestBlendAlpha = D3D12_BLEND_SRC_ALPHA;
29924     pso_desc.BlendState.RenderTarget[1].DestBlend = D3D12_BLEND_SRC_COLOR;
29925     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
29926             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
29927     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
29928     context.pipeline_state = NULL;
29929 
29930     pso_desc.NumRenderTargets = 2;
29931     pso_desc.RTVFormats[1] = pso_desc.RTVFormats[0];
29932     pso_desc.BlendState.IndependentBlendEnable = false;
29933     pso_desc.BlendState.RenderTarget[0].BlendEnable = true;
29934     pso_desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_COLOR;
29935     pso_desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_SRC1_COLOR;
29936     pso_desc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
29937     pso_desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA;
29938     pso_desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_SRC1_ALPHA;
29939     pso_desc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
29940     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
29941             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
29942     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
29943 
29944     destroy_test_context(&context);
29945 }
29946 
test_multisample_rendering(void)29947 static void test_multisample_rendering(void)
29948 {
29949     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
29950     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
29951     ID3D12GraphicsCommandList *command_list;
29952     ID3D12PipelineState *ms_pipeline_state;
29953     D3D12_CPU_DESCRIPTOR_HANDLE ms_rtv;
29954     ID3D12Resource *ms_render_target;
29955     struct test_context_desc desc;
29956     struct test_context context;
29957     ID3D12DescriptorHeap *heap;
29958     ID3D12CommandQueue *queue;
29959     uint32_t sample;
29960     unsigned int i;
29961     HRESULT hr;
29962 
29963     static const DWORD ps_color_code[] =
29964     {
29965 #if 0
29966         float4 main(uint id : SV_SampleIndex) : SV_Target
29967         {
29968             switch (id)
29969             {
29970                 case 0:  return float4(1.0f, 0.0f, 0.0f, 1.0f);
29971                 case 1:  return float4(0.0f, 1.0f, 0.0f, 1.0f);
29972                 case 2:  return float4(0.0f, 0.0f, 1.0f, 1.0f);
29973                 default: return float4(0.0f, 0.0f, 0.0f, 1.0f);
29974             }
29975         }
29976 #endif
29977         0x43425844, 0x94c35f48, 0x04c6b0f7, 0x407d8214, 0xc24f01e5, 0x00000001, 0x00000194, 0x00000003,
29978         0x0000002c, 0x00000064, 0x00000098, 0x4e475349, 0x00000030, 0x00000001, 0x00000008, 0x00000020,
29979         0x00000000, 0x0000000a, 0x00000001, 0x00000000, 0x00000101, 0x535f5653, 0x6c706d61, 0x646e4965,
29980         0xab007865, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
29981         0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000f4,
29982         0x00000050, 0x0000003d, 0x0100086a, 0x04000863, 0x00101012, 0x00000000, 0x0000000a, 0x03000065,
29983         0x001020f2, 0x00000000, 0x0300004c, 0x0010100a, 0x00000000, 0x03000006, 0x00004001, 0x00000000,
29984         0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000,
29985         0x0100003e, 0x03000006, 0x00004001, 0x00000001, 0x08000036, 0x001020f2, 0x00000000, 0x00004002,
29986         0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x0100003e, 0x03000006, 0x00004001, 0x00000002,
29987         0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,
29988         0x0100003e, 0x0100000a, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
29989         0x00000000, 0x3f800000, 0x0100003e, 0x01000017, 0x0100003e,
29990     };
29991     static const D3D12_SHADER_BYTECODE ps_color = {ps_color_code, sizeof(ps_color_code)};
29992     static const DWORD ps_resolve_code[] =
29993     {
29994 #if 0
29995         Texture2DMS<float4> t;
29996 
29997         uint sample;
29998         uint rt_size;
29999 
30000         float4 main(float4 position : SV_Position) : SV_Target
30001         {
30002             float3 p;
30003             t.GetDimensions(p.x, p.y, p.z);
30004             p *= float3(position.x / rt_size, position.y / rt_size, 0);
30005             return t.Load((int2)p.xy, sample);
30006         }
30007 #endif
30008         0x43425844, 0x68a4590b, 0xc1ec3070, 0x1b957c43, 0x0c080741, 0x00000001, 0x000001c8, 0x00000003,
30009         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
30010         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
30011         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
30012         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000012c, 0x00000050,
30013         0x0000004b, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04002058, 0x00107000,
30014         0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2,
30015         0x00000000, 0x02000068, 0x00000001, 0x06000056, 0x00100012, 0x00000000, 0x0020801a, 0x00000000,
30016         0x00000000, 0x0700000e, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00100006, 0x00000000,
30017         0x8900003d, 0x80000102, 0x00155543, 0x001000c2, 0x00000000, 0x00004001, 0x00000000, 0x001074e6,
30018         0x00000000, 0x07000038, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00100ae6, 0x00000000,
30019         0x0500001b, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x08000036, 0x001000c2, 0x00000000,
30020         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8c00002e, 0x80000102, 0x00155543,
30021         0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00107e46, 0x00000000, 0x0020800a, 0x00000000,
30022         0x00000000, 0x0100003e,
30023     };
30024     static const D3D12_SHADER_BYTECODE ps_resolve = {ps_resolve_code, sizeof(ps_resolve_code)};
30025     static const unsigned int expected_colors[] = {0xff0000ff, 0xff00ff00, 0xffff0000, 0xff000000};
30026 
30027     if (use_warp_device)
30028     {
30029         skip("Sample shading tests fail on WARP.\n");
30030         return;
30031     }
30032 
30033     memset(&desc, 0, sizeof(desc));
30034     desc.rt_width = desc.rt_height = 32;
30035     desc.rt_descriptor_count = 2;
30036     desc.no_root_signature = true;
30037     if (!init_test_context(&context, &desc))
30038         return;
30039     command_list = context.list;
30040     queue = context.queue;
30041 
30042     context.root_signature = create_texture_root_signature(context.device,
30043             D3D12_SHADER_VISIBILITY_PIXEL, 2, 0);
30044 
30045     init_pipeline_state_desc(&pso_desc, context.root_signature,
30046             context.render_target_desc.Format, NULL, &ps_resolve, NULL);
30047     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
30048             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
30049     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
30050 
30051     pso_desc.PS = ps_color;
30052     pso_desc.SampleDesc.Count = 4;
30053     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
30054             &IID_ID3D12PipelineState, (void **)&ms_pipeline_state);
30055     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
30056 
30057     ms_rtv = get_cpu_rtv_handle(&context, context.rtv_heap, 1);
30058     desc.sample_desc.Count = 4;
30059     create_render_target(&context, &desc, &ms_render_target, &ms_rtv);
30060 
30061     heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
30062     ID3D12Device_CreateShaderResourceView(context.device, ms_render_target, NULL,
30063             get_cpu_descriptor_handle(&context, heap, 0));
30064 
30065     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
30066     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, ms_rtv, white, 0, NULL);
30067     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &ms_rtv, false, NULL);
30068     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
30069     ID3D12GraphicsCommandList_SetPipelineState(command_list, ms_pipeline_state);
30070     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
30071     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
30072     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
30073     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
30074     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
30075             get_gpu_descriptor_handle(&context, heap, 0));
30076     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
30077 
30078     transition_resource_state(command_list, ms_render_target,
30079             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
30080     transition_resource_state(command_list, context.render_target,
30081             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_DEST);
30082     ID3D12GraphicsCommandList_ResolveSubresource(command_list,
30083             context.render_target, 0, ms_render_target, 0, context.render_target_desc.Format);
30084     transition_resource_state(command_list, ms_render_target,
30085             D3D12_RESOURCE_STATE_RESOLVE_SOURCE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
30086     transition_resource_state(command_list, context.render_target,
30087             D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
30088     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff404040, 2);
30089 
30090     for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
30091     {
30092         reset_command_list(command_list, context.allocator);
30093         transition_resource_state(command_list, context.render_target,
30094                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
30095 
30096         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
30097         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
30098         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
30099         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
30100         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
30101         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
30102         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
30103         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
30104         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
30105                 get_gpu_descriptor_handle(&context, heap, 0));
30106         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 1, &desc.rt_width, 1);
30107 
30108         sample = i;
30109         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 1, &sample, 0);
30110         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
30111 
30112         transition_resource_state(command_list, context.render_target,
30113                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
30114         check_sub_resource_uint(context.render_target, 0, queue, command_list, expected_colors[i], 0);
30115     }
30116 
30117     ID3D12DescriptorHeap_Release(heap);
30118     ID3D12Resource_Release(ms_render_target);
30119     ID3D12PipelineState_Release(ms_pipeline_state);
30120     destroy_test_context(&context);
30121 }
30122 
test_sample_mask(void)30123 static void test_sample_mask(void)
30124 {
30125     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
30126     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
30127     ID3D12GraphicsCommandList *command_list;
30128     D3D12_CPU_DESCRIPTOR_HANDLE ms_rtv;
30129     ID3D12Resource *ms_render_target;
30130     struct test_context_desc desc;
30131     struct test_context context;
30132     ID3D12CommandQueue *queue;
30133     uint32_t sample_mask;
30134     HRESULT hr;
30135 
30136     static const DWORD ps_code[] =
30137     {
30138 #if 0
30139         uint mask;
30140 
30141         float4 main(in float4 pos : SV_Position, out uint sample_mask : SV_Coverage) : SV_Target
30142         {
30143             sample_mask = mask;
30144             return float4(0.0, 1.0, 0.0, 1.0);
30145         }
30146 #endif
30147         0x43425844, 0xfab05c6c, 0xeba1b017, 0xf4493502, 0x72ce5d05, 0x00000001, 0x00000128, 0x00000003,
30148         0x0000002c, 0x00000060, 0x000000b8, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
30149         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69,
30150         0x4e47534f, 0x00000050, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000000, 0x00000003,
30151         0x00000000, 0x0000000f, 0x00000042, 0x00000000, 0x00000000, 0x00000001, 0xffffffff, 0x00000e01,
30152         0x545f5653, 0x65677261, 0x56530074, 0x766f435f, 0x67617265, 0xabab0065, 0x58454853, 0x00000068,
30153         0x00000050, 0x0000001a, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065,
30154         0x001020f2, 0x00000000, 0x02000065, 0x0000f000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002,
30155         0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x05000036, 0x0000f001, 0x0020800a, 0x00000000,
30156         0x00000000, 0x0100003e,
30157     };
30158     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
30159 
30160     memset(&desc, 0, sizeof(desc));
30161     desc.rt_descriptor_count = 2;
30162     desc.no_root_signature = true;
30163     if (!init_test_context(&context, &desc))
30164         return;
30165     command_list = context.list;
30166     queue = context.queue;
30167 
30168     context.root_signature = create_32bit_constants_root_signature(context.device,
30169             0, 1, D3D12_SHADER_VISIBILITY_PIXEL);
30170 
30171     init_pipeline_state_desc(&pso_desc, context.root_signature,
30172             context.render_target_desc.Format, NULL, &ps, NULL);
30173     pso_desc.SampleDesc.Count = 4;
30174     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
30175             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
30176     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
30177 
30178     ms_rtv = get_cpu_rtv_handle(&context, context.rtv_heap, 1);
30179     desc.sample_desc.Count = 4;
30180     create_render_target(&context, &desc, &ms_render_target, &ms_rtv);
30181 
30182     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
30183     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, ms_rtv, white, 0, NULL);
30184     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &ms_rtv, false, NULL);
30185     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
30186     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
30187     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
30188     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
30189     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
30190     sample_mask = 0xa;
30191     ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0, 1, &sample_mask, 0);
30192     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
30193 
30194     transition_resource_state(command_list, ms_render_target,
30195             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
30196     transition_resource_state(command_list, context.render_target,
30197             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_DEST);
30198     ID3D12GraphicsCommandList_ResolveSubresource(command_list,
30199             context.render_target, 0, ms_render_target, 0, context.render_target_desc.Format);
30200     transition_resource_state(command_list, context.render_target,
30201             D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
30202     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff7fff7f, 2);
30203 
30204     ID3D12Resource_Release(ms_render_target);
30205     destroy_test_context(&context);
30206 }
30207 
test_coverage(void)30208 static void test_coverage(void)
30209 {
30210     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
30211     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
30212     D3D12_DESCRIPTOR_RANGE descriptor_ranges[1];
30213     ID3D12DescriptorHeap *cpu_heap, *gpu_heap;
30214     ID3D12GraphicsCommandList *command_list;
30215     D3D12_ROOT_PARAMETER root_parameters[1];
30216     struct test_context_desc desc;
30217     struct test_context context;
30218     ID3D12CommandQueue *queue;
30219     ID3D12Resource *texture;
30220     unsigned int i;
30221     HRESULT hr;
30222 
30223     static const float black[4];
30224     static const unsigned int zero[4];
30225     static const DWORD ps_code[] =
30226     {
30227 #if 0
30228         RWTexture2D<uint> u;
30229 
30230         float4 main(float4 position : SV_Position, uint coverage : SV_Coverage) : SV_Target
30231         {
30232             InterlockedOr(u[uint2(position.x, position.y)], coverage);
30233             return float4(0.0, 1.0, 0.0, 1.0);
30234         }
30235 #endif
30236         0x43425844, 0x53236006, 0x68a61a42, 0x5d0a06e7, 0x05a9405b, 0x00000001, 0x00000134, 0x00000003,
30237         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
30238         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x7469736f, 0x006e6f69,
30239         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
30240         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000098, 0x00000050,
30241         0x00000026, 0x0100086a, 0x0400189c, 0x0011e000, 0x00000001, 0x00004444, 0x04002064, 0x00101032,
30242         0x00000000, 0x00000001, 0x0200005f, 0x00023001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
30243         0x00000001, 0x0500001c, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x060000aa, 0x0011e000,
30244         0x00000001, 0x00100046, 0x00000000, 0x0002300a, 0x08000036, 0x001020f2, 0x00000000, 0x00004002,
30245         0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x0100003e,
30246     };
30247     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
30248 
30249     static const struct
30250     {
30251         unsigned int sample_mask;
30252         unsigned int expected_color;
30253     }
30254     tests[] =
30255     {
30256         {0x01, 0x40004000},
30257         {0x03, 0x7f007f00},
30258         {0x07, 0xbf00bf00},
30259         {0x09, 0x7f007f00},
30260         {0x0d, 0xbf00bf00},
30261         {0x0f, 0xff00ff00},
30262         {0xff, 0xff00ff00},
30263         { ~0u, 0xff00ff00},
30264     };
30265 
30266     if (use_warp_device)
30267     {
30268         skip("Sample shading tests fail on WARP.\n");
30269         return;
30270     }
30271 
30272     memset(&desc, 0, sizeof(desc));
30273     desc.rt_width = desc.rt_height = 32;
30274     desc.sample_desc.Count = 4;
30275     desc.no_root_signature = true;
30276     if (!init_test_context(&context, &desc))
30277         return;
30278     command_list = context.list;
30279     queue = context.queue;
30280 
30281     descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
30282     descriptor_ranges[0].NumDescriptors = 1;
30283     descriptor_ranges[0].BaseShaderRegister = 1;
30284     descriptor_ranges[0].RegisterSpace = 0;
30285     descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0;
30286     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
30287     root_parameters[0].DescriptorTable.NumDescriptorRanges = ARRAY_SIZE(descriptor_ranges);
30288     root_parameters[0].DescriptorTable.pDescriptorRanges = descriptor_ranges;
30289     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
30290     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
30291     root_signature_desc.pParameters = root_parameters;
30292     root_signature_desc.NumStaticSamplers = 0;
30293     root_signature_desc.pStaticSamplers = NULL;
30294     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
30295     hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
30296     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
30297 
30298     texture = create_default_texture(context.device, desc.rt_width, desc.rt_height, DXGI_FORMAT_R32_UINT,
30299             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
30300 
30301     cpu_heap = create_cpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
30302     gpu_heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
30303     ID3D12Device_CreateUnorderedAccessView(context.device, texture, NULL, NULL,
30304             get_cpu_descriptor_handle(&context, cpu_heap, 0));
30305     ID3D12Device_CopyDescriptorsSimple(context.device, 1,
30306             get_cpu_descriptor_handle(&context, gpu_heap, 0),
30307             get_cpu_descriptor_handle(&context, cpu_heap, 0),
30308             D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
30309 
30310     for (i = 0; i < ARRAY_SIZE(tests); ++i)
30311     {
30312         vkd3d_test_set_context("sample mask %#x", tests[i].sample_mask);
30313 
30314         if (context.pipeline_state)
30315             ID3D12PipelineState_Release(context.pipeline_state);
30316 
30317         init_pipeline_state_desc(&pso_desc, context.root_signature,
30318                 context.render_target_desc.Format, NULL, &ps, NULL);
30319         pso_desc.SampleMask = tests[i].sample_mask;
30320         pso_desc.SampleDesc.Count = desc.sample_desc.Count;
30321         hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
30322                 &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
30323         ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
30324 
30325         ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(command_list,
30326                 get_gpu_descriptor_handle(&context, gpu_heap, 0),
30327                 get_cpu_descriptor_handle(&context, cpu_heap, 0),
30328                 texture, zero, 0, NULL);
30329 
30330         uav_barrier(command_list, texture);
30331 
30332         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, black, 0, NULL);
30333         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
30334         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
30335         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
30336         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
30337         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
30338         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
30339         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &gpu_heap);
30340         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list,
30341                 0, get_gpu_descriptor_handle(&context, gpu_heap, 0));
30342         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
30343 
30344         transition_resource_state(command_list, context.render_target,
30345                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
30346         check_sub_resource_uint(context.render_target, 0, queue, command_list, tests[i].expected_color, 2);
30347 
30348         reset_command_list(command_list, context.allocator);
30349         transition_resource_state(command_list, texture,
30350                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
30351         check_sub_resource_uint(texture, 0, queue, command_list, tests[i].sample_mask & 0xf, 0);
30352 
30353         reset_command_list(command_list, context.allocator);
30354         transition_resource_state(command_list, context.render_target,
30355                 D3D12_RESOURCE_STATE_RESOLVE_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
30356         transition_resource_state(command_list, texture,
30357                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
30358     }
30359     vkd3d_test_set_context(NULL);
30360 
30361     ID3D12DescriptorHeap_Release(cpu_heap);
30362     ID3D12DescriptorHeap_Release(gpu_heap);
30363     ID3D12Resource_Release(texture);
30364     destroy_test_context(&context);
30365 }
30366 
test_shader_get_render_target_sample_count(void)30367 static void test_shader_get_render_target_sample_count(void)
30368 {
30369     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
30370     ID3D12GraphicsCommandList *command_list;
30371     struct test_context_desc desc;
30372     struct test_context context;
30373     ID3D12CommandQueue *queue;
30374     HRESULT hr;
30375 
30376     static const float black[4];
30377     static const DWORD ps_code[] =
30378     {
30379 #if 0
30380         float4 main() : SV_Target
30381         {
30382             return GetRenderTargetSampleCount();
30383         }
30384 
30385 #endif
30386         0x43425844, 0x74404d37, 0xad6f88e4, 0xb006ea57, 0xf07d9e2a, 0x00000001, 0x000000a4, 0x00000003,
30387         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
30388         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
30389         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000002c, 0x00000050, 0x0000000b,
30390         0x0100086a, 0x03000065, 0x001020f2, 0x00000000, 0x0400006f, 0x001020f2, 0x00000000, 0x0000e00a,
30391         0x0100003e,
30392     };
30393     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
30394     static const struct vec4 sample_count = {8.0f, 8.0f, 8.0f, 8.0f};
30395 
30396     memset(&desc, 0, sizeof(desc));
30397     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
30398     desc.sample_desc.Count = 8;
30399     desc.no_pipeline = true;
30400     if (!init_test_context(&context, &desc))
30401         return;
30402     command_list = context.list;
30403     queue = context.queue;
30404 
30405     init_pipeline_state_desc(&pso_desc, context.root_signature,
30406             context.render_target_desc.Format, NULL, &ps, NULL);
30407     pso_desc.SampleDesc.Count = desc.sample_desc.Count;
30408     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
30409             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
30410     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
30411 
30412     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, black, 0, NULL);
30413     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
30414     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
30415     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
30416     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
30417     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
30418     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
30419     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
30420 
30421     transition_resource_state(command_list, context.render_target,
30422             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
30423     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &sample_count, 0);
30424 
30425     destroy_test_context(&context);
30426 }
30427 
test_shader_sample_position(void)30428 static void test_shader_sample_position(void)
30429 {
30430     D3D12_TEXTURE_COPY_LOCATION src_location, dst_location;
30431     ID3D12Resource *texture, *readback_texture;
30432     ID3D12GraphicsCommandList *command_list;
30433     D3D12_HEAP_PROPERTIES heap_properties;
30434     D3D12_RESOURCE_DESC resource_desc;
30435     struct test_context_desc desc;
30436     struct resource_readback rb;
30437     struct test_context context;
30438     ID3D12DescriptorHeap *heap;
30439     ID3D12CommandQueue *queue;
30440     uint32_t sample_index;
30441     unsigned int i;
30442     D3D12_BOX box;
30443     HRESULT hr;
30444 
30445     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
30446     static const DWORD ps_code[] =
30447     {
30448 #if 0
30449         uint index;
30450         Texture2DMS<float4> t;
30451 
30452         float4 main() : SV_Target
30453         {
30454             return float4(t.GetSamplePosition(index), 0, 0);
30455         }
30456 #endif
30457         0x43425844, 0x89611945, 0x2b7e06f0, 0x953a72bb, 0x1590618f, 0x00000001, 0x000000f8, 0x00000003,
30458         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
30459         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
30460         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000080, 0x00000050, 0x00000020,
30461         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x04002058, 0x00107000, 0x00000000,
30462         0x00005555, 0x03000065, 0x001020f2, 0x00000000, 0x0900006e, 0x00102032, 0x00000000, 0x00107046,
30463         0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000000,
30464         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e,
30465     };
30466     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
30467 
30468     memset(&desc, 0, sizeof(desc));
30469     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
30470     desc.rt_width = desc.rt_height = 1;
30471     desc.no_root_signature = true;
30472     if (!init_test_context(&context, &desc))
30473         return;
30474     command_list = context.list;
30475     queue = context.queue;
30476 
30477     context.root_signature = create_texture_root_signature(context.device,
30478             D3D12_SHADER_VISIBILITY_PIXEL, 1, 0);
30479     context.pipeline_state = create_pipeline_state(context.device,
30480             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
30481 
30482     memset(&heap_properties, 0, sizeof(heap_properties));
30483     heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
30484     resource_desc = ID3D12Resource_GetDesc(context.render_target);
30485     resource_desc.SampleDesc.Count = 4;
30486     hr = ID3D12Device_CreateCommittedResource(context.device,
30487             &heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
30488             D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, (void **)&texture);
30489     ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
30490 
30491     heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 16);
30492     readback_texture = create_default_texture(context.device, 4, 1, DXGI_FORMAT_R32G32B32A32_FLOAT,
30493             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
30494     ID3D12Device_CreateShaderResourceView(context.device, texture, NULL,
30495             ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap));
30496 
30497     transition_resource_state(command_list,
30498             texture, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
30499 
30500     for (sample_index = 0; sample_index < resource_desc.SampleDesc.Count; ++sample_index)
30501     {
30502         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
30503         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
30504         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
30505         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
30506         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
30507         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
30508         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
30509         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
30510         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
30511                 get_gpu_descriptor_handle(&context, heap, 0));
30512         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 1, &sample_index, 0);
30513         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
30514 
30515         transition_resource_state(command_list, context.render_target,
30516                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
30517         src_location.pResource = context.render_target;
30518         src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
30519         src_location.SubresourceIndex = 0;
30520         dst_location.pResource = readback_texture;
30521         dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
30522         dst_location.SubresourceIndex = 0;
30523         set_box(&box, 0, 0, 0, 1, 1, 1);
30524         ID3D12GraphicsCommandList_CopyTextureRegion(command_list, &dst_location, sample_index, 0, 0, &src_location, &box);
30525         transition_resource_state(command_list, context.render_target,
30526                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
30527     }
30528 
30529     transition_resource_state(command_list, readback_texture,
30530             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
30531 
30532     get_texture_readback_with_command_list(readback_texture, 0, &rb, queue, command_list);
30533     for (i = 0; i < resource_desc.SampleDesc.Count; ++i)
30534     {
30535         const struct vec4 *position = get_readback_vec4(&rb, i, 0);
30536 
30537         vkd3d_test_set_context("Sample %u", i);
30538 
30539         ok(-1.0f <= position->x && position->x <= 1.0f, "Unexpected x %.8e.\n", position->x);
30540         ok(-1.0f <= position->y && position->y <= 1.0f, "Unexpected y %.8e.\n", position->y);
30541         ok(!position->z, "Unexpected z %.8e.\n", position->z);
30542         ok(!position->w, "Unexpected w %.8e.\n", position->w);
30543 
30544         if (vkd3d_test_state.debug_level > 0)
30545             trace("Sample %u position {%.8e, %.8e}.\n", i, position->x, position->y);
30546 
30547         vkd3d_test_set_context(NULL);
30548     }
30549     release_resource_readback(&rb);
30550 
30551     ID3D12DescriptorHeap_Release(heap);
30552     ID3D12Resource_Release(texture);
30553     ID3D12Resource_Release(readback_texture);
30554     destroy_test_context(&context);
30555 }
30556 
test_shader_eval_attribute(void)30557 static void test_shader_eval_attribute(void)
30558 {
30559     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
30560     ID3D12GraphicsCommandList *command_list;
30561     struct test_context_desc desc;
30562     struct test_context context;
30563     ID3D12CommandQueue *queue;
30564     HRESULT hr;
30565 
30566     static const DWORD vs_code[] =
30567     {
30568 #if 0
30569         void main(uint id : SV_VertexID, out float4 position : SV_Position,
30570                 out float2 attr : ATTR, out centroid float2 ref : REF)
30571         {
30572             float2 coords = float2((id << 1) & 2, id & 2);
30573             position = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1);
30574             attr = ref = position.xy;
30575         }
30576 #endif
30577         0x43425844, 0x9289815f, 0xc6ff580d, 0xa7184c61, 0x4920e2eb, 0x00000001, 0x0000021c, 0x00000003,
30578         0x0000002c, 0x00000060, 0x000000d0, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
30579         0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000101, 0x565f5653, 0x65747265, 0x00444978,
30580         0x4e47534f, 0x00000068, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, 0x00000003,
30581         0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000c03,
30582         0x00000061, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x505f5653, 0x7469736f,
30583         0x006e6f69, 0x52545441, 0x46455200, 0xababab00, 0x58454853, 0x00000144, 0x00010050, 0x00000051,
30584         0x0100086a, 0x04000060, 0x00101012, 0x00000000, 0x00000006, 0x04000067, 0x001020f2, 0x00000000,
30585         0x00000001, 0x03000065, 0x00102032, 0x00000001, 0x03000065, 0x00102032, 0x00000002, 0x02000068,
30586         0x00000001, 0x0b00008c, 0x00100012, 0x00000000, 0x00004001, 0x00000001, 0x00004001, 0x00000001,
30587         0x0010100a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100042, 0x00000000, 0x0010100a,
30588         0x00000000, 0x00004001, 0x00000002, 0x05000056, 0x00100032, 0x00000000, 0x00100086, 0x00000000,
30589         0x0f000032, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00004002, 0x40000000, 0xc0000000,
30590         0x00000000, 0x00000000, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000, 0x05000036,
30591         0x00102032, 0x00000000, 0x00100046, 0x00000000, 0x08000036, 0x001020c2, 0x00000000, 0x00004002,
30592         0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x05000036, 0x00102032, 0x00000001, 0x00100046,
30593         0x00000000, 0x05000036, 0x00102032, 0x00000002, 0x00100046, 0x00000000, 0x0100003e,
30594     };
30595     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
30596     static const DWORD ps_eval_sample_index_code[] =
30597     {
30598 #if 0
30599         float4 main(float4 p : SV_Position, float2 attr : ATTR,
30600                 sample float2 ref : REF, uint sample_id : SV_SampleIndex) : SV_Target
30601         {
30602             return float4(EvaluateAttributeAtSample(attr, sample_id) - ref, 0, 1);
30603         }
30604 #endif
30605         0x43425844, 0x65f268a1, 0x2c1a3d53, 0xd39689a5, 0x2f556a12, 0x00000001, 0x000001a4, 0x00000003,
30606         0x0000002c, 0x000000c0, 0x000000f4, 0x4e475349, 0x0000008c, 0x00000004, 0x00000008, 0x00000068,
30607         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000074, 0x00000000, 0x00000000,
30608         0x00000003, 0x00000001, 0x00000303, 0x00000079, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
30609         0x00000303, 0x0000007d, 0x00000000, 0x0000000a, 0x00000001, 0x00000003, 0x00000101, 0x505f5653,
30610         0x7469736f, 0x006e6f69, 0x52545441, 0x46455200, 0x5f565300, 0x706d6153, 0x6e49656c, 0x00786564,
30611         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
30612         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000a8, 0x00000050,
30613         0x0000002a, 0x0100086a, 0x03001062, 0x00101032, 0x00000001, 0x03003062, 0x00101032, 0x00000002,
30614         0x04000863, 0x00101012, 0x00000003, 0x0000000a, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
30615         0x00000001, 0x070000cc, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x0010100a, 0x00000003,
30616         0x08000000, 0x00102032, 0x00000000, 0x00100046, 0x00000000, 0x80101046, 0x00000041, 0x00000002,
30617         0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,
30618         0x0100003e,
30619     };
30620     static const D3D12_SHADER_BYTECODE ps_eval_sample_index = {ps_eval_sample_index_code, sizeof(ps_eval_sample_index_code)};
30621     static const DWORD vs_eval_centroid_code[] =
30622     {
30623 #if 0
30624         void main(uint id : SV_VertexID, out float4 position : SV_Position,
30625                 out float2 attr : ATTR, out float2 attr2 : ATTR2, out centroid float2 ref : REF)
30626         {
30627             float2 coords = float2((id << 1) & 2, id & 2);
30628             position = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1);
30629             attr = attr2 = ref = position.xy;
30630         }
30631 #endif
30632         0x43425844, 0xed41033d, 0xa2906698, 0x319dcb84, 0x41750935, 0x00000001, 0x00000240, 0x00000003,
30633         0x0000002c, 0x00000060, 0x000000e8, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
30634         0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000101, 0x565f5653, 0x65747265, 0x00444978,
30635         0x4e47534f, 0x00000080, 0x00000004, 0x00000008, 0x00000068, 0x00000000, 0x00000001, 0x00000003,
30636         0x00000000, 0x0000000f, 0x00000074, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000c03,
30637         0x00000074, 0x00000002, 0x00000000, 0x00000003, 0x00000001, 0x0000030c, 0x00000079, 0x00000000,
30638         0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x505f5653, 0x7469736f, 0x006e6f69, 0x52545441,
30639         0x46455200, 0xababab00, 0x58454853, 0x00000150, 0x00010050, 0x00000054, 0x0100086a, 0x04000060,
30640         0x00101012, 0x00000000, 0x00000006, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065,
30641         0x00102032, 0x00000001, 0x03000065, 0x001020c2, 0x00000001, 0x03000065, 0x00102032, 0x00000002,
30642         0x02000068, 0x00000001, 0x0b00008c, 0x00100012, 0x00000000, 0x00004001, 0x00000001, 0x00004001,
30643         0x00000001, 0x0010100a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100042, 0x00000000,
30644         0x0010100a, 0x00000000, 0x00004001, 0x00000002, 0x05000056, 0x00100032, 0x00000000, 0x00100086,
30645         0x00000000, 0x0f000032, 0x00100032, 0x00000000, 0x00100046, 0x00000000, 0x00004002, 0x40000000,
30646         0xc0000000, 0x00000000, 0x00000000, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000,
30647         0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000000, 0x08000036, 0x001020c2, 0x00000000,
30648         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x05000036, 0x001020f2, 0x00000001,
30649         0x00100446, 0x00000000, 0x05000036, 0x00102032, 0x00000002, 0x00100046, 0x00000000, 0x0100003e,
30650     };
30651     static const D3D12_SHADER_BYTECODE vs_eval_centroid = {vs_eval_centroid_code, sizeof(vs_eval_centroid_code)};
30652     static const DWORD ps_eval_centroid_code[] =
30653     {
30654 #if 0
30655         float4 main(float4 p : SV_Position, float2 attr : ATTR, float2 attr2 : ATTR2, centroid float2 ref : REF) : SV_Target
30656         {
30657             return float4(EvaluateAttributeCentroid(attr) - ref, 0, 1);
30658         }
30659 #endif
30660         0x43425844, 0x8ec53803, 0xdfd9505b, 0x8d4ce8ad, 0xbbefe3d4, 0x00000001, 0x00000180, 0x00000003,
30661         0x0000002c, 0x000000b4, 0x000000e8, 0x4e475349, 0x00000080, 0x00000004, 0x00000008, 0x00000068,
30662         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000074, 0x00000000, 0x00000000,
30663         0x00000003, 0x00000001, 0x00000303, 0x00000074, 0x00000002, 0x00000000, 0x00000003, 0x00000001,
30664         0x0000000c, 0x00000079, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000303, 0x505f5653,
30665         0x7469736f, 0x006e6f69, 0x52545441, 0x46455200, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001,
30666         0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653,
30667         0x65677261, 0xabab0074, 0x58454853, 0x00000090, 0x00000050, 0x00000024, 0x0100086a, 0x03001062,
30668         0x00101032, 0x00000001, 0x03001862, 0x00101032, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
30669         0x02000068, 0x00000001, 0x050000cd, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x08000000,
30670         0x00102032, 0x00000000, 0x00100046, 0x00000000, 0x80101046, 0x00000041, 0x00000002, 0x08000036,
30671         0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e,
30672     };
30673     static const D3D12_SHADER_BYTECODE ps_eval_centroid = {ps_eval_centroid_code, sizeof(ps_eval_centroid_code)};
30674     static const struct vec4 expected_vec4 = {0.0f, 0.0f, 0.0f, 1.0f};
30675     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
30676 
30677     if (use_warp_device)
30678     {
30679         skip("Sample shading tests fail on WARP.\n");
30680         return;
30681     }
30682 
30683     memset(&desc, 0, sizeof(desc));
30684     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
30685     desc.rt_width = desc.rt_height = 32;
30686     desc.sample_desc.Count = 4;
30687     desc.no_pipeline = true;
30688     if (!init_test_context(&context, &desc))
30689         return;
30690     command_list = context.list;
30691     queue = context.queue;
30692 
30693     init_pipeline_state_desc(&pso_desc, context.root_signature,
30694             context.render_target_desc.Format, &vs, &ps_eval_sample_index, NULL);
30695     pso_desc.SampleDesc.Count = desc.sample_desc.Count;
30696     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
30697             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
30698     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
30699 
30700     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
30701     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
30702     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
30703     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
30704     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
30705     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
30706     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
30707     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
30708 
30709     transition_resource_state(command_list, context.render_target,
30710             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
30711     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_vec4, 0);
30712 
30713     reset_command_list(command_list, context.allocator);
30714     transition_resource_state(command_list, context.render_target,
30715             D3D12_RESOURCE_STATE_RESOLVE_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
30716 
30717     ID3D12PipelineState_Release(context.pipeline_state);
30718     pso_desc.VS = vs_eval_centroid;
30719     pso_desc.PS = ps_eval_centroid;
30720     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
30721             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
30722     ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
30723 
30724     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
30725     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
30726     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
30727     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
30728     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
30729     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
30730     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
30731     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
30732 
30733     transition_resource_state(command_list, context.render_target,
30734             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
30735     check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_vec4, 0);
30736 
30737     destroy_test_context(&context);
30738 }
30739 
test_primitive_restart(void)30740 static void test_primitive_restart(void)
30741 {
30742     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
30743     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
30744     ID3D12GraphicsCommandList *command_list;
30745     D3D12_INPUT_LAYOUT_DESC input_layout;
30746     struct test_context_desc desc;
30747     D3D12_VERTEX_BUFFER_VIEW vbv;
30748     struct test_context context;
30749     D3D12_INDEX_BUFFER_VIEW ibv;
30750     struct resource_readback rb;
30751     ID3D12CommandQueue *queue;
30752     unsigned int index_count;
30753     ID3D12Resource *ib, *vb;
30754     size_t buffer_size;
30755     unsigned int i;
30756     D3D12_BOX box;
30757     HRESULT hr;
30758     void *ptr;
30759 
30760     static const DWORD vs_code[] =
30761     {
30762 #if 0
30763         float4 main(int4 p : POSITION) : SV_Position
30764         {
30765             return p;
30766         }
30767 #endif
30768         0x43425844, 0x3fd50ab1, 0x580a1d14, 0x28f5f602, 0xd1083e3a, 0x00000001, 0x000000d8, 0x00000003,
30769         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
30770         0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
30771         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
30772         0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x52444853, 0x0000003c, 0x00010040,
30773         0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
30774         0x0500002b, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
30775     };
30776     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
30777     static const struct
30778     {
30779         int8_t x, y;
30780     }
30781     quad[] =
30782     {
30783         {-1, -1},
30784         {-1,  1},
30785         { 1, -1},
30786         { 1,  1},
30787     };
30788     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
30789     {
30790         {"position", 0, DXGI_FORMAT_R8G8_SINT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
30791     };
30792     static const uint16_t indices16[] = {0, 1, 2, 3};
30793     static const uint32_t indices[] = {0, 1, 2, 3};
30794     static const uint16_t indices16_max[] = {0, 1, 2, 0xffff};
30795     static const uint32_t indices_max16[] = {0, 1, 2, 0xffff};
30796     static const uint16_t indices16_restart[] = {0, 1, 2, 0xffff, 2, 1, 3};
30797     static const uint32_t indices_restart[] = {0, 1, 2, 0xffffffff, 2, 1, 3};
30798     static const struct
30799     {
30800         D3D12_INDEX_BUFFER_STRIP_CUT_VALUE strip_cut_value;
30801         DXGI_FORMAT ib_format;
30802         const void *indices;
30803         size_t indices_size;
30804         unsigned int last_index;
30805         bool full_quad;
30806         bool is_todo;
30807     }
30808     tests[] =
30809     {
30810         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED, DXGI_FORMAT_R16_UINT,     indices16,     sizeof(indices16), 0x0003, true},
30811         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED, DXGI_FORMAT_R16_UINT, indices16_max, sizeof(indices16_max), 0xffff, true},
30812         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED, DXGI_FORMAT_R32_UINT,       indices,       sizeof(indices), 0x0003, true},
30813         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED, DXGI_FORMAT_R32_UINT, indices_max16, sizeof(indices_max16), 0xffff, true},
30814 
30815         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF, DXGI_FORMAT_R16_UINT,     indices16,     sizeof(indices16), 0x0003, true},
30816         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF, DXGI_FORMAT_R16_UINT, indices16_max, sizeof(indices16_max), 0xffff, false},
30817         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF, DXGI_FORMAT_R16_UINT, indices16_restart, sizeof(indices16_restart), 0x0003, true},
30818         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF, DXGI_FORMAT_R32_UINT,       indices,       sizeof(indices), 0x0003, true},
30819         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF, DXGI_FORMAT_R32_UINT, indices_max16, sizeof(indices_max16), 0xffff, false, true},
30820 
30821         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF, DXGI_FORMAT_R16_UINT,     indices16,     sizeof(indices16), 0x0003, true},
30822         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF, DXGI_FORMAT_R16_UINT, indices16_max, sizeof(indices16_max), 0xffff, true, true},
30823         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF, DXGI_FORMAT_R32_UINT,       indices,       sizeof(indices), 0x0003, true},
30824         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF, DXGI_FORMAT_R32_UINT, indices_max16, sizeof(indices_max16), 0xffff, true},
30825         {D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF, DXGI_FORMAT_R32_UINT, indices_restart, sizeof(indices_restart), 0x0003, true},
30826     };
30827 
30828     memset(&desc, 0, sizeof(desc));
30829     desc.no_root_signature = true;
30830     if (!init_test_context(&context, &desc))
30831         return;
30832     command_list = context.list;
30833     queue = context.queue;
30834 
30835     context.root_signature = create_empty_root_signature(context.device,
30836             D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
30837     input_layout.pInputElementDescs = layout_desc;
30838     input_layout.NumElements = ARRAY_SIZE(layout_desc);
30839     init_pipeline_state_desc(&pso_desc, context.root_signature,
30840             context.render_target_desc.Format, &vs, NULL, &input_layout);
30841 
30842     for (i = 0; i < ARRAY_SIZE(tests); ++i)
30843     {
30844         vkd3d_test_set_context("Test %u", i);
30845 
30846         buffer_size = (tests[i].last_index + 1) * sizeof(*quad);
30847 
30848         vb = create_upload_buffer(context.device, buffer_size, NULL);
30849         vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
30850         vbv.StrideInBytes = sizeof(*quad);
30851         vbv.SizeInBytes = buffer_size;
30852 
30853         pso_desc.IBStripCutValue = tests[i].strip_cut_value;
30854         hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
30855                 &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
30856         ok(hr == S_OK, "Failed to create pipeline, hr %#x.\n", hr);
30857 
30858         ibv.Format = tests[i].ib_format;
30859         ib = create_upload_buffer(context.device, tests[i].indices_size, tests[i].indices);
30860         ibv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(ib);
30861         ibv.SizeInBytes = tests[i].indices_size;
30862         index_count = tests[i].indices_size / format_size(ibv.Format);
30863 
30864         hr = ID3D12Resource_Map(vb, 0, NULL, &ptr);
30865         ok(hr == S_OK, "Failed to map buffer, hr %#x.\n", hr);
30866         memcpy(ptr, quad, (ARRAY_SIZE(quad) - 1) * sizeof(*quad));
30867         memcpy((BYTE *)ptr + tests[i].last_index * sizeof(*quad), &quad[ARRAY_SIZE(quad) - 1], sizeof(*quad));
30868         ID3D12Resource_Unmap(vb, 0, NULL);
30869 
30870         ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
30871 
30872         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
30873         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
30874         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
30875         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
30876         ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
30877         ID3D12GraphicsCommandList_IASetIndexBuffer(command_list, &ibv);
30878         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
30879         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
30880         ID3D12GraphicsCommandList_DrawIndexedInstanced(command_list, index_count, 1, 0, 0, 0);
30881 
30882         transition_resource_state(command_list, context.render_target,
30883                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
30884         get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
30885         if (tests[i].full_quad)
30886         {
30887             todo_if(tests[i].is_todo)
30888             check_readback_data_uint(&rb, NULL, 0xff00ff00, 0);
30889         }
30890         else
30891         {
30892             set_box(&box, 16, 0, 0, 32, 10, 1);
30893             todo_if(tests[i].is_todo)
30894             check_readback_data_uint(&rb, &box, 0xffffffff, 0);
30895             set_box(&box, 0, 16, 0, 16, 32, 1);
30896             check_readback_data_uint(&rb, &box, 0xff00ff00, 0);
30897         }
30898         release_resource_readback(&rb);
30899 
30900         reset_command_list(command_list, context.allocator);
30901         transition_resource_state(command_list, context.render_target,
30902                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
30903 
30904         ID3D12Resource_Release(ib);
30905         ID3D12Resource_Release(vb);
30906         ID3D12PipelineState_Release(context.pipeline_state);
30907         context.pipeline_state = NULL;
30908     }
30909     vkd3d_test_set_context(NULL);
30910 
30911     destroy_test_context(&context);
30912 }
30913 
test_vertex_shader_stream_output(void)30914 static void test_vertex_shader_stream_output(void)
30915 {
30916     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
30917     ID3D12Resource *counter_buffer, *so_buffer;
30918     ID3D12GraphicsCommandList *command_list;
30919     D3D12_STREAM_OUTPUT_BUFFER_VIEW sobv;
30920     ID3D12Resource *upload_buffer;
30921     struct test_context_desc desc;
30922     struct resource_readback rb;
30923     struct test_context context;
30924     ID3D12CommandQueue *queue;
30925     unsigned int counter, i;
30926     const struct vec4 *data;
30927     ID3D12Device *device;
30928     HRESULT hr;
30929 
30930     static const D3D12_SO_DECLARATION_ENTRY so_declaration[] =
30931     {
30932         {0, "SV_Position", 0, 0, 4, 0},
30933     };
30934     static const struct vec4 expected_output[] =
30935     {
30936         {-1.0f, 1.0f, 0.0f, 1.0f},
30937         { 3.0f, 1.0f, 0.0f, 1.0f},
30938         {-1.0f,-3.0f, 0.0f, 1.0f},
30939     };
30940     unsigned int strides[] = {16};
30941 
30942     memset(&desc, 0, sizeof(desc));
30943     desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT;
30944     desc.no_pipeline = true;
30945     if (!init_test_context(&context, &desc))
30946         return;
30947     device = context.device;
30948     command_list = context.list;
30949     queue = context.queue;
30950 
30951     init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, NULL, NULL);
30952     pso_desc.StreamOutput.NumEntries = ARRAY_SIZE(so_declaration);
30953     pso_desc.StreamOutput.pSODeclaration = so_declaration;
30954     pso_desc.StreamOutput.pBufferStrides = strides;
30955     pso_desc.StreamOutput.NumStrides = ARRAY_SIZE(strides);
30956     pso_desc.StreamOutput.RasterizedStream = D3D12_SO_NO_RASTERIZED_STREAM;
30957     hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
30958             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
30959     if (hr == E_NOTIMPL)
30960     {
30961         skip("Stream output is not supported.\n");
30962         destroy_test_context(&context);
30963         return;
30964     }
30965     ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
30966 
30967     counter = 0;
30968     upload_buffer = create_upload_buffer(device, sizeof(counter), &counter);
30969 
30970     counter_buffer = create_default_buffer(device, 32,
30971             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
30972     so_buffer = create_default_buffer(device, 1024,
30973             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_STREAM_OUT);
30974     sobv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(so_buffer);
30975     sobv.SizeInBytes = 1024;
30976     sobv.BufferFilledSizeLocation = ID3D12Resource_GetGPUVirtualAddress(counter_buffer);
30977 
30978     ID3D12GraphicsCommandList_CopyBufferRegion(command_list, counter_buffer, 0,
30979             upload_buffer, 0, sizeof(counter));
30980 
30981     transition_resource_state(command_list, counter_buffer,
30982             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_STREAM_OUT);
30983 
30984     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
30985     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
30986     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
30987     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
30988     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
30989     ID3D12GraphicsCommandList_SOSetTargets(command_list, 0, 1, &sobv);
30990     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
30991 
30992     transition_resource_state(command_list, counter_buffer,
30993             D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
30994     transition_resource_state(command_list, so_buffer,
30995             D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
30996 
30997     get_buffer_readback_with_command_list(counter_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
30998     counter = get_readback_uint(&rb, 0, 0, 0);
30999     ok(counter == 3 * sizeof(struct vec4), "Got unexpected counter %u.\n", counter);
31000     release_resource_readback(&rb);
31001     reset_command_list(command_list, context.allocator);
31002     get_buffer_readback_with_command_list(so_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
31003     for (i = 0; i < ARRAY_SIZE(expected_output); ++i)
31004     {
31005         const struct vec4 *expected = &expected_output[i];
31006         data = get_readback_vec4(&rb, i, 0);
31007         ok(compare_vec4(data, expected, 1),
31008                 "Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
31009                 data->x, data->y, data->z, data->w, expected->x, expected->y, expected->z, expected->w);
31010     }
31011     release_resource_readback(&rb);
31012 
31013     ID3D12Resource_Release(counter_buffer);
31014     ID3D12Resource_Release(upload_buffer);
31015     ID3D12Resource_Release(so_buffer);
31016     destroy_test_context(&context);
31017 }
31018 
test_read_write_subresource(void)31019 static void test_read_write_subresource(void)
31020 {
31021     D3D12_TEXTURE_COPY_LOCATION src_location, dst_location;
31022     uint32_t *dst_buffer, *zero_buffer, *ptr;
31023     ID3D12GraphicsCommandList *command_list;
31024     D3D12_HEAP_PROPERTIES heap_properties;
31025     D3D12_SUBRESOURCE_DATA texture_data;
31026     D3D12_RESOURCE_DESC resource_desc;
31027     struct test_context_desc desc;
31028     struct test_context context;
31029     struct resource_readback rb;
31030     ID3D12Resource *src_texture;
31031     ID3D12Resource *dst_texture;
31032     ID3D12CommandQueue *queue;
31033     ID3D12Resource *rb_buffer;
31034     unsigned int buffer_size;
31035     unsigned int slice_pitch;
31036     unsigned int x, y, z, i;
31037     unsigned int row_pitch;
31038     uint32_t got, expected;
31039     ID3D12Device *device;
31040     D3D12_BOX box;
31041     HRESULT hr;
31042 
31043     memset(&desc, 0, sizeof(desc));
31044     desc.no_render_target = true;
31045     if (!init_test_context(&context, &desc))
31046         return;
31047     device = context.device;
31048     command_list = context.list;
31049     queue = context.queue;
31050 
31051     row_pitch = 128 * sizeof(unsigned int);
31052     slice_pitch = row_pitch * 100;
31053     buffer_size = slice_pitch * 64;
31054 
31055     /* Buffers are not supported */
31056     rb_buffer = create_readback_buffer(device, buffer_size);
31057     dst_buffer = malloc(buffer_size);
31058     ok(dst_buffer, "Failed to allocate memory.\n");
31059     zero_buffer = malloc(buffer_size);
31060     ok(zero_buffer, "Failed to allocate memory.\n");
31061     memset(zero_buffer, 0, buffer_size);
31062 
31063     set_box(&box, 0, 0, 0, 1, 1, 1);
31064     hr = ID3D12Resource_WriteToSubresource(rb_buffer, 0, &box, dst_buffer, row_pitch, slice_pitch);
31065     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
31066 
31067     hr = ID3D12Resource_ReadFromSubresource(rb_buffer, dst_buffer, row_pitch, slice_pitch, 0, &box);
31068     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
31069 
31070     ID3D12Resource_Release(rb_buffer);
31071 
31072     /* Only texture on custom heaps is legal for ReadFromSubresource/WriteToSubresource */
31073     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D;
31074     resource_desc.Alignment = 0;
31075     resource_desc.Width = 128;
31076     resource_desc.Height = 100;
31077     resource_desc.DepthOrArraySize = 64;
31078     resource_desc.MipLevels = 1;
31079     resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
31080     resource_desc.SampleDesc.Count = 1;
31081     resource_desc.SampleDesc.Quality = 0;
31082     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
31083     resource_desc.Flags = 0;
31084 
31085     memset(&heap_properties, 0, sizeof(heap_properties));
31086     heap_properties.Type = D3D12_HEAP_TYPE_CUSTOM;
31087     heap_properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK;
31088     heap_properties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0;
31089     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
31090             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, (void **)&src_texture);
31091     if (FAILED(hr))
31092     {
31093         skip("Failed to create texture on custom heap.\n");
31094         goto done;
31095     }
31096 
31097     /* Invalid box */
31098     set_box(&box, 0, 0, 0, 128, 100, 65);
31099     hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
31100     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
31101 
31102     set_box(&box, 0, 0, 65, 128, 100, 65);
31103     hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
31104     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
31105 
31106     set_box(&box, 128, 0, 0, 128, 100, 65);
31107     hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
31108     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
31109 
31110     /* NULL box */
31111     hr = ID3D12Resource_WriteToSubresource(src_texture, 0, NULL, dst_buffer, row_pitch, slice_pitch);
31112     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
31113 
31114     hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, NULL);
31115     todo_if(is_nvidia_device(device))
31116     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
31117 
31118     /* Empty box */
31119     set_box(&box, 128, 100, 64, 128, 100, 64);
31120     hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
31121     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
31122 
31123     set_box(&box, 0, 0, 0, 0, 0, 0);
31124     hr = ID3D12Resource_WriteToSubresource(src_texture, 0, &box, dst_buffer, row_pitch, slice_pitch);
31125     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
31126 
31127     hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
31128     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
31129 
31130     for (i = 0; i < 2; ++i)
31131     {
31132         vkd3d_test_set_context("Test %u", i);
31133 
31134         for (z = 0; z < 64; ++z)
31135         {
31136             for (y = 0; y < 100; ++y)
31137             {
31138                 for (x = 0; x < 128; ++x)
31139                 {
31140                     ptr = &dst_buffer[z * 128 * 100 + y * 128 + x];
31141                     if (x < 2 && y< 2 && z < 2) /* Region 1 */
31142                         *ptr = (z + 1) << 16 | (y + 1) << 8 | (x + 1);
31143                     else if (2 <= x && x < 11 && 2 <= y && y < 13 && 2 <= z && z < 17) /* Region 2 */
31144                         *ptr = (z + 2) << 16 | (y + 2) << 8 | (x + 2);
31145                     else
31146                         *ptr = 0xdeadbeef;
31147                 }
31148             }
31149         }
31150 
31151         if (i)
31152         {
31153             hr = ID3D12Resource_WriteToSubresource(src_texture, 0, NULL, zero_buffer, row_pitch, slice_pitch);
31154             ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
31155 
31156             /* Write region 1 */
31157             set_box(&box, 0, 0, 0, 2, 2, 2);
31158             hr = ID3D12Resource_WriteToSubresource(src_texture, 0, &box, dst_buffer, row_pitch, slice_pitch);
31159             ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
31160 
31161             /* Write region 2 */
31162             set_box(&box, 2, 2, 2, 11, 13, 17);
31163             hr = ID3D12Resource_WriteToSubresource(src_texture, 0, &box, &dst_buffer[2 * 128 * 100 + 2 * 128 + 2],
31164                     row_pitch, slice_pitch);
31165             ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
31166         }
31167         else
31168         {
31169             /* Upload the test data */
31170             transition_resource_state(command_list, src_texture,
31171                     D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST);
31172             texture_data.pData = dst_buffer;
31173             texture_data.RowPitch = row_pitch;
31174             texture_data.SlicePitch = slice_pitch;
31175             upload_texture_data(src_texture, &texture_data, 1, queue, command_list);
31176             reset_command_list(command_list, context.allocator);
31177             transition_resource_state(command_list, src_texture,
31178                     D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COMMON);
31179         }
31180 
31181         memset(dst_buffer, 0, buffer_size);
31182 
31183         /* Read region 1 */
31184         set_box(&box, 0, 0, 0, 2, 2, 2);
31185         hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
31186         todo_if(is_nvidia_device(device))
31187         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
31188 
31189         /* Read region 2 */
31190         set_box(&box, 2, 2, 2, 11, 13, 17);
31191         hr = ID3D12Resource_ReadFromSubresource(src_texture, &dst_buffer[2 * 128 * 100 + 2 * 128 + 2], row_pitch,
31192                 slice_pitch, 0, &box);
31193         todo_if(is_nvidia_device(device))
31194         ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
31195 
31196         for (z = 0; z < 64; ++z)
31197         {
31198             for (y = 0; y < 100; ++y)
31199             {
31200                 for (x = 0; x < 128; ++x)
31201                 {
31202                     if (x < 2 && y < 2 && z < 2) /* Region 1 */
31203                         expected = (z + 1) << 16 | (y + 1) << 8 | (x + 1);
31204                     else if (2 <= x && x < 11 && 2 <= y && y < 13 && 2 <= z && z < 17) /* Region 2 */
31205                         expected = (z + 2) << 16 | (y + 2) << 8 | (x + 2);
31206                     else /* Untouched */
31207                         expected = 0;
31208 
31209                     got = dst_buffer[z * 128 * 100 + y * 128 + x];
31210                     if (got != expected)
31211                         break;
31212                 }
31213                 if (got != expected)
31214                     break;
31215             }
31216             if (got != expected)
31217                 break;
31218         }
31219         todo_if(is_nvidia_device(device))
31220         ok(got == expected, "Got unexpected value 0x%08x at (%u, %u, %u), expected 0x%08x.\n", got, x, y, z, expected);
31221     }
31222     vkd3d_test_set_context(NULL);
31223 
31224     /* Test layout is the same */
31225     dst_texture = create_default_texture3d(device, 128, 100, 64, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0,
31226             D3D12_RESOURCE_STATE_COPY_DEST);
31227     memset(dst_buffer, 0, buffer_size);
31228     texture_data.pData = dst_buffer;
31229     texture_data.RowPitch = row_pitch;
31230     texture_data.SlicePitch = slice_pitch;
31231     upload_texture_data(dst_texture, &texture_data, 1, queue, command_list);
31232     reset_command_list(command_list, context.allocator);
31233 
31234     src_location.pResource = src_texture;
31235     src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
31236     src_location.SubresourceIndex = 0;
31237     dst_location.pResource = dst_texture;
31238     dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
31239     dst_location.SubresourceIndex = 0;
31240     set_box(&box, 0, 0, 0, 128, 100, 64);
31241     ID3D12GraphicsCommandList_CopyTextureRegion(command_list, &dst_location, 0, 0, 0, &src_location, &box);
31242 
31243     transition_resource_state(command_list, dst_texture,
31244             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
31245     get_texture_readback_with_command_list(dst_texture, 0, &rb, queue, command_list);
31246     for (z = 0; z < 64; ++z)
31247     {
31248         for (y = 0; y < 100; ++y)
31249         {
31250             for (x = 0; x < 128; ++x)
31251             {
31252                 if (x < 2 && y < 2 && z < 2) /* Region 1 */
31253                     expected = (z + 1) << 16 | (y + 1) << 8 | (x + 1);
31254                 else if (2 <= x && x < 11 && 2 <= y && y < 13 && 2 <= z && z < 17) /* Region 2 */
31255                     expected = (z + 2) << 16 | (y + 2) << 8 | (x + 2);
31256                 else /* Untouched */
31257                     expected = 0;
31258 
31259                 got = get_readback_uint(&rb, x, y, z);
31260                 if (got != expected)
31261                     break;
31262             }
31263             if (got != expected)
31264                 break;
31265         }
31266         if (got != expected)
31267             break;
31268     }
31269     ok(got == expected, "Got unexpected value 0x%08x at (%u, %u, %u), expected 0x%08x.\n", got, x, y, z, expected);
31270     release_resource_readback(&rb);
31271 
31272     ID3D12Resource_Release(src_texture);
31273     ID3D12Resource_Release(dst_texture);
31274 
31275     /* Invalid box */
31276     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
31277     resource_desc.Alignment = 0;
31278     resource_desc.Width = 64;
31279     resource_desc.Height = 32;
31280     resource_desc.DepthOrArraySize = 1;
31281     resource_desc.MipLevels = 1;
31282     resource_desc.Format = DXGI_FORMAT_BC1_UNORM;
31283     resource_desc.SampleDesc.Count = 1;
31284     resource_desc.SampleDesc.Quality = 0;
31285     resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
31286     resource_desc.Flags = 0;
31287 
31288     memset(&heap_properties, 0, sizeof(heap_properties));
31289     heap_properties.Type = D3D12_HEAP_TYPE_CUSTOM;
31290     heap_properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK;
31291     heap_properties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0;
31292     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
31293             &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, (void **)&src_texture);
31294     ok(hr == S_OK, "Failed to create resource, hr %#x.\n", hr);
31295 
31296     /* Unaligned coordinates for BC format */
31297     set_box(&box, 0, 0, 0, 2, 2, 1);
31298     hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
31299     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
31300 
31301     set_box(&box, 2, 2, 0, 4, 4, 1);
31302     hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
31303     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
31304 
31305     set_box(&box, 2, 2, 0, 6, 6, 1);
31306     hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
31307     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
31308 
31309     /* Invalid coordinates for resource dimensions */
31310     set_box(&box, 0, 0, 0, 64, 32, 2);
31311     hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
31312     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
31313 
31314     set_box(&box, 0, 0, 0, 68, 32, 1);
31315     hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
31316     ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
31317 
31318     ID3D12Resource_Release(src_texture);
31319 
31320 done:
31321     free(dst_buffer);
31322     free(zero_buffer);
31323     destroy_test_context(&context);
31324 }
31325 
test_queue_wait(void)31326 static void test_queue_wait(void)
31327 {
31328     D3D12_TEXTURE_COPY_LOCATION dst_location, src_location;
31329     ID3D12GraphicsCommandList *command_list;
31330     ID3D12Resource *readback_buffer, *cb;
31331     ID3D12CommandQueue *queue, *queue2;
31332     D3D12_RESOURCE_DESC resource_desc;
31333     uint64_t row_pitch, buffer_size;
31334     struct test_context_desc desc;
31335     struct resource_readback rb;
31336     ID3D12Fence *fence, *fence2;
31337     struct test_context context;
31338     ID3D12Device *device;
31339     unsigned int ret;
31340     uint64_t value;
31341     float color[4];
31342     HANDLE event;
31343     HRESULT hr;
31344 
31345     static const float blue[] = {0.0f, 0.0f, 1.0f, 1.0f};
31346     static const float green[] = {0.0f, 1.0f, 0.0f, 1.0f};
31347     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
31348     static const DWORD ps_code[] =
31349     {
31350 #if 0
31351         float4 color;
31352 
31353         float4 main(float4 position : SV_POSITION) : SV_Target
31354         {
31355             return color;
31356         }
31357 #endif
31358         0x43425844, 0xd18ead43, 0x8b8264c1, 0x9c0a062d, 0xfc843226, 0x00000001, 0x000000e0, 0x00000003,
31359         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
31360         0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49,
31361         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
31362         0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000044, 0x00000050,
31363         0x00000011, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2,
31364         0x00000000, 0x06000036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e,
31365     };
31366     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
31367 
31368     memset(&desc, 0, sizeof(desc));
31369     desc.no_root_signature = true;
31370     if (!init_test_context(&context, &desc))
31371         return;
31372     device = context.device;
31373     command_list = context.list;
31374     queue = context.queue;
31375 
31376     queue2 = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
31377 
31378     event = create_event();
31379     ok(event, "Failed to create event.\n");
31380 
31381     hr = ID3D12Device_CreateFence(device, 1, D3D12_FENCE_FLAG_NONE, &IID_ID3D12Fence, (void **)&fence);
31382     ok(hr == S_OK, "Failed to create fence, hr %#x.\n", hr);
31383     hr = ID3D12Device_CreateFence(device, 0, D3D12_FENCE_FLAG_NONE, &IID_ID3D12Fence, (void **)&fence2);
31384     ok(hr == S_OK, "Failed to create fence, hr %#x.\n", hr);
31385 
31386     context.root_signature = create_cb_root_signature(context.device,
31387             0, D3D12_SHADER_VISIBILITY_PIXEL, D3D12_ROOT_SIGNATURE_FLAG_NONE);
31388     context.pipeline_state = create_pipeline_state(context.device,
31389             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
31390 
31391     cb = create_upload_buffer(device, sizeof(color), NULL);
31392 
31393     resource_desc = ID3D12Resource_GetDesc(context.render_target);
31394 
31395     row_pitch = align(resource_desc.Width * format_size(resource_desc.Format), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
31396     buffer_size = row_pitch * resource_desc.Height;
31397     readback_buffer = create_readback_buffer(device, buffer_size);
31398 
31399     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
31400     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
31401     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
31402     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
31403     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
31404     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
31405     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
31406     ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(command_list, 0,
31407             ID3D12Resource_GetGPUVirtualAddress(cb));
31408     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
31409 
31410     transition_resource_state(command_list, context.render_target,
31411             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
31412 
31413     dst_location.pResource = readback_buffer;
31414     dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
31415     dst_location.PlacedFootprint.Offset = 0;
31416     dst_location.PlacedFootprint.Footprint.Format = resource_desc.Format;
31417     dst_location.PlacedFootprint.Footprint.Width = resource_desc.Width;
31418     dst_location.PlacedFootprint.Footprint.Height = resource_desc.Height;
31419     dst_location.PlacedFootprint.Footprint.Depth = 1;
31420     dst_location.PlacedFootprint.Footprint.RowPitch = row_pitch;
31421     src_location.pResource = context.render_target;
31422     src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
31423     src_location.SubresourceIndex = 0;
31424     ID3D12GraphicsCommandList_CopyTextureRegion(command_list, &dst_location, 0, 0, 0, &src_location, NULL);
31425 
31426     transition_resource_state(command_list, context.render_target,
31427             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
31428 
31429     hr = ID3D12GraphicsCommandList_Close(command_list);
31430     ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr);
31431 
31432     /* Wait() with signaled fence */
31433     update_buffer_data(cb, 0, sizeof(green), &green);
31434     queue_wait(queue, fence, 1);
31435     exec_command_list(queue, command_list);
31436     wait_queue_idle(device, queue);
31437     init_readback(&rb, readback_buffer, buffer_size, resource_desc.Width, resource_desc.Height, 1, row_pitch);
31438     check_readback_data_uint(&rb, NULL, 0xff00ff00, 0);
31439     release_resource_readback(&rb);
31440 
31441     if (!vkd3d_test_platform_is_windows())
31442     {
31443         skip("Wait() is not implemented yet.\n"); /* FIXME */
31444         goto skip_tests;
31445     }
31446 
31447     /* Wait() before CPU signal */
31448     update_buffer_data(cb, 0, sizeof(blue), &blue);
31449     queue_wait(queue, fence, 2);
31450     exec_command_list(queue, command_list);
31451     queue_signal(queue, fence2, 1);
31452     hr = ID3D12Fence_SetEventOnCompletion(fence2, 1, event);
31453     ok(hr == S_OK, "Failed to set event on completion, hr %#x.\n", hr);
31454     ret = wait_event(event, 0);
31455     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
31456     init_readback(&rb, readback_buffer, buffer_size, resource_desc.Width, resource_desc.Height, 1, row_pitch);
31457     check_readback_data_uint(&rb, NULL, 0xff00ff00, 0);
31458     release_resource_readback(&rb);
31459     value = ID3D12Fence_GetCompletedValue(fence2);
31460     ok(value == 0, "Got unexpected value %"PRIu64".\n", value);
31461 
31462     hr = ID3D12Fence_Signal(fence, 2);
31463     ok(hr == S_OK, "Failed to signal fence, hr %#x.\n", hr);
31464     ret = wait_event(event, INFINITE);
31465     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
31466     ret = wait_event(event, 0);
31467     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
31468     init_readback(&rb, readback_buffer, buffer_size, resource_desc.Width, resource_desc.Height, 1, row_pitch);
31469     check_readback_data_uint(&rb, NULL, 0xffff0000, 0);
31470     release_resource_readback(&rb);
31471     value = ID3D12Fence_GetCompletedValue(fence2);
31472     ok(value == 1, "Got unexpected value %"PRIu64".\n", value);
31473 
31474     /* Wait() before GPU signal */
31475     update_buffer_data(cb, 0, sizeof(green), &green);
31476     queue_wait(queue, fence, 3);
31477     exec_command_list(queue, command_list);
31478     queue_signal(queue, fence2, 2);
31479     hr = ID3D12Fence_SetEventOnCompletion(fence2, 2, event);
31480     ok(hr == S_OK, "Failed to set event on completion, hr %#x.\n", hr);
31481     ret = wait_event(event, 0);
31482     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
31483     init_readback(&rb, readback_buffer, buffer_size, resource_desc.Width, resource_desc.Height, 1, row_pitch);
31484     check_readback_data_uint(&rb, NULL, 0xffff0000, 0);
31485     release_resource_readback(&rb);
31486     value = ID3D12Fence_GetCompletedValue(fence2);
31487     ok(value == 1, "Got unexpected value %"PRIu64".\n", value);
31488 
31489     queue_signal(queue2, fence, 3);
31490     ret = wait_event(event, INFINITE);
31491     ok(ret == WAIT_OBJECT_0, "Got unexpected return value %#x.\n", ret);
31492     ret = wait_event(event, 0);
31493     ok(ret == WAIT_TIMEOUT, "Got unexpected return value %#x.\n", ret);
31494     init_readback(&rb, readback_buffer, buffer_size, resource_desc.Width, resource_desc.Height, 1, row_pitch);
31495     check_readback_data_uint(&rb, NULL, 0xff00ff00, 0);
31496     release_resource_readback(&rb);
31497     value = ID3D12Fence_GetCompletedValue(fence2);
31498     ok(value == 2, "Got unexpected value %"PRIu64".\n", value);
31499 
31500     /* update constant buffer after Wait() */
31501     queue_wait(queue, fence, 5);
31502     exec_command_list(queue, command_list);
31503     hr = ID3D12Fence_Signal(fence, 4);
31504     ok(hr == S_OK, "Failed to signal fence, hr %#x.\n", hr);
31505     update_buffer_data(cb, 0, sizeof(blue), &blue);
31506     hr = ID3D12Fence_Signal(fence, 5);
31507     ok(hr == S_OK, "Failed to signal fence, hr %#x.\n", hr);
31508     wait_queue_idle(device, queue);
31509     init_readback(&rb, readback_buffer, buffer_size, resource_desc.Width, resource_desc.Height, 1, row_pitch);
31510     check_readback_data_uint(&rb, NULL, 0xffff0000, 0);
31511     release_resource_readback(&rb);
31512 
31513     hr = ID3D12Fence_Signal(fence, 6);
31514     ok(hr == S_OK, "Failed to signal fence, hr %#x.\n", hr);
31515     update_buffer_data(cb, 0, sizeof(green), &green);
31516     exec_command_list(queue, command_list);
31517     wait_queue_idle(device, queue);
31518     init_readback(&rb, readback_buffer, buffer_size, resource_desc.Width, resource_desc.Height, 1, row_pitch);
31519     check_readback_data_uint(&rb, NULL, 0xff00ff00, 0);
31520     release_resource_readback(&rb);
31521 
31522 skip_tests:
31523     /* Signal() and Wait() in the same command queue */
31524     update_buffer_data(cb, 0, sizeof(blue), &blue);
31525     queue_signal(queue, fence, 7);
31526     queue_wait(queue, fence, 7);
31527     exec_command_list(queue, command_list);
31528     wait_queue_idle(device, queue);
31529     init_readback(&rb, readback_buffer, buffer_size, resource_desc.Width, resource_desc.Height, 1, row_pitch);
31530     check_readback_data_uint(&rb, NULL, 0xffff0000, 0);
31531     release_resource_readback(&rb);
31532 
31533     value = ID3D12Fence_GetCompletedValue(fence);
31534     ok(value == 7, "Got unexpected value %"PRIu64".\n", value);
31535 
31536     destroy_event(event);
31537     ID3D12Fence_Release(fence);
31538     ID3D12Fence_Release(fence2);
31539     ID3D12Resource_Release(cb);
31540     ID3D12CommandQueue_Release(queue2);
31541     ID3D12Resource_Release(readback_buffer);
31542     destroy_test_context(&context);
31543 }
31544 
test_graphics_compute_queue_synchronization(void)31545 static void test_graphics_compute_queue_synchronization(void)
31546 {
31547     ID3D12GraphicsCommandList *graphics_lists[2], *compute_lists[2];
31548     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
31549     ID3D12PipelineState *compute_pipeline_state;
31550     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
31551     ID3D12CommandQueue *queue, *compute_queue;
31552     ID3D12DescriptorHeap *cpu_heap, *gpu_heap;
31553     ID3D12GraphicsCommandList *command_list;
31554     D3D12_ROOT_PARAMETER root_parameters[2];
31555     ID3D12CommandAllocator *allocators[3];
31556     struct test_context_desc desc;
31557     struct resource_readback rb;
31558     struct test_context context;
31559     ID3D12Fence *fence, *fence2;
31560     ID3D12Resource *buffer;
31561     ID3D12Device *device;
31562     uint32_t value;
31563     unsigned int i;
31564     HRESULT hr;
31565 
31566     unsigned int clear_value[4] = {0};
31567     static const DWORD cs_code[] =
31568     {
31569 #if 0
31570         uint expected_value;
31571         RWByteAddressBuffer u : register(u1);
31572 
31573         [numthreads(64, 1, 1)]
31574         void main(void)
31575         {
31576             u.InterlockedCompareStore(0, expected_value, expected_value + 10);
31577         }
31578 #endif
31579         0x43425844, 0x7909aab0, 0xf8576455, 0x58f9dd61, 0x3e7e64f0, 0x00000001, 0x000000e0, 0x00000003,
31580         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
31581         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x0000008c, 0x00050050, 0x00000023, 0x0100086a,
31582         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300009d, 0x0011e000, 0x00000001, 0x02000068,
31583         0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001, 0x0800001e, 0x00100012, 0x00000000,
31584         0x0020800a, 0x00000000, 0x00000000, 0x00004001, 0x0000000a, 0x0a0000ac, 0x0011e000, 0x00000001,
31585         0x00004001, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0010000a, 0x00000000, 0x0100003e,
31586     };
31587     static const DWORD ps_code[] =
31588     {
31589 #if 0
31590         uint expected_value;
31591         RWByteAddressBuffer u;
31592 
31593         float4 main(void) : SV_Target
31594         {
31595             u.InterlockedCompareStore(0, expected_value, expected_value + 2);
31596             return float4(0, 1, 0, 1);
31597         }
31598 #endif
31599         0x43425844, 0x82fbce04, 0xa014204c, 0xc4d46d91, 0x1081c7a7, 0x00000001, 0x00000120, 0x00000003,
31600         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
31601         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
31602         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x000000a8, 0x00000050, 0x0000002a,
31603         0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300009d, 0x0011e000, 0x00000001,
31604         0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0800001e, 0x00100012, 0x00000000,
31605         0x0020800a, 0x00000000, 0x00000000, 0x00004001, 0x00000002, 0x0a0000ac, 0x0011e000, 0x00000001,
31606         0x00004001, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0010000a, 0x00000000, 0x08000036,
31607         0x001020f2, 0x00000000, 0x00004002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x0100003e,
31608     };
31609     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
31610 
31611     memset(&desc, 0, sizeof(desc));
31612     desc.no_root_signature = true;
31613     if (!init_test_context(&context, &desc))
31614         return;
31615     device = context.device;
31616     queue = context.queue;
31617 
31618     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
31619     root_parameters[0].Descriptor.ShaderRegister = 1;
31620     root_parameters[0].Descriptor.RegisterSpace = 0;
31621     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
31622     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
31623     root_parameters[1].Constants.ShaderRegister = 0;
31624     root_parameters[1].Constants.RegisterSpace = 0;
31625     root_parameters[1].Constants.Num32BitValues = 1;
31626     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
31627     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
31628     root_signature_desc.pParameters = root_parameters;
31629     root_signature_desc.NumStaticSamplers = 0;
31630     root_signature_desc.pStaticSamplers = NULL;
31631     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
31632     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
31633     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
31634 
31635     compute_pipeline_state = create_compute_pipeline_state(device, context.root_signature,
31636             shader_bytecode(cs_code, sizeof(cs_code)));
31637     context.pipeline_state = create_pipeline_state(context.device,
31638             context.root_signature, context.render_target_desc.Format, NULL, &ps, NULL);
31639 
31640     compute_queue = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_COMPUTE, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
31641     hr = ID3D12Device_CreateFence(device, 0, D3D12_FENCE_FLAG_NONE, &IID_ID3D12Fence, (void **)&fence);
31642     ok(hr == S_OK, "Failed to create fence, hr %#x.\n", hr);
31643     hr = ID3D12Device_CreateFence(device, 0, D3D12_FENCE_FLAG_NONE, &IID_ID3D12Fence, (void **)&fence2);
31644     ok(hr == S_OK, "Failed to create fence, hr %#x.\n", hr);
31645 
31646     buffer = create_default_buffer(device, 1024,
31647             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
31648 
31649     hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT,
31650             &IID_ID3D12CommandAllocator, (void **)&allocators[0]);
31651     ok(hr == S_OK, "Failed to create command allocator, hr %#x.\n", hr);
31652     hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT,
31653             allocators[0], NULL, &IID_ID3D12GraphicsCommandList, (void **)&graphics_lists[0]);
31654     ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
31655 
31656     graphics_lists[1] = context.list;
31657     ID3D12GraphicsCommandList_AddRef(graphics_lists[1]);
31658 
31659     for (i = 0; i < ARRAY_SIZE(compute_lists); ++i)
31660     {
31661         hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_COMPUTE,
31662                 &IID_ID3D12CommandAllocator, (void **)&allocators[i + 1]);
31663         ok(hr == S_OK, "Failed to create command allocator, hr %#x.\n", hr);
31664         hr = ID3D12Device_CreateCommandList(device, 0, D3D12_COMMAND_LIST_TYPE_COMPUTE,
31665                 allocators[i + 1], NULL, &IID_ID3D12GraphicsCommandList, (void **)&compute_lists[i]);
31666         ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
31667     }
31668 
31669     cpu_heap = create_cpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
31670     gpu_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
31671 
31672     memset(&uav_desc, 0, sizeof(uav_desc));
31673     uav_desc.Format = DXGI_FORMAT_R32_UINT;
31674     uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
31675     uav_desc.Buffer.NumElements = 1024 / sizeof(uint32_t);
31676     ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc,
31677             get_cpu_descriptor_handle(&context, cpu_heap, 0));
31678     ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc,
31679             get_cpu_descriptor_handle(&context, gpu_heap, 0));
31680 
31681     ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(compute_lists[0],
31682             get_gpu_descriptor_handle(&context, gpu_heap, 0),
31683             get_cpu_descriptor_handle(&context, cpu_heap, 0),
31684             buffer, clear_value, 0, NULL);
31685     uav_barrier(compute_lists[0], buffer);
31686 
31687     value = 0;
31688     for (i = 0; i < ARRAY_SIZE(compute_lists); ++i)
31689     {
31690         command_list = compute_lists[i];
31691 
31692         ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
31693         ID3D12GraphicsCommandList_SetPipelineState(command_list, compute_pipeline_state);
31694         ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list,
31695                 0, ID3D12Resource_GetGPUVirtualAddress(buffer));
31696         ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(command_list, 1, 1, &value, 0);
31697         ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
31698         hr = ID3D12GraphicsCommandList_Close(command_list);
31699         ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr);
31700 
31701         value += 10;
31702 
31703         command_list = graphics_lists[i];
31704 
31705         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
31706         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
31707         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
31708         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
31709         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
31710         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
31711         ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView(command_list,
31712                 0, ID3D12Resource_GetGPUVirtualAddress(buffer));
31713         ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 1, 1, &value, 0);
31714         ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
31715         hr = ID3D12GraphicsCommandList_Close(command_list);
31716         ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr);
31717 
31718         value += 2;
31719     }
31720 
31721     exec_command_list(compute_queue, compute_lists[0]);
31722     queue_signal(compute_queue, fence, 1);
31723 
31724     queue_wait(queue, fence, 1);
31725     exec_command_list(queue, graphics_lists[0]);
31726     queue_signal(queue, fence2, 1);
31727 
31728     queue_wait(compute_queue, fence2, 1);
31729     exec_command_list(compute_queue, compute_lists[1]);
31730     queue_signal(compute_queue, fence, 2);
31731 
31732     queue_wait(queue, fence, 2);
31733     exec_command_list(queue, graphics_lists[1]);
31734 
31735     hr = wait_for_fence(fence2, 1);
31736     ok(hr == S_OK, "Failed to wait for fence, hr %#x.\n", hr);
31737     reset_command_list(graphics_lists[0], allocators[0]);
31738     command_list = graphics_lists[0];
31739 
31740     transition_resource_state(command_list, buffer,
31741             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
31742     get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
31743     value = get_readback_uint(&rb, 0, 0, 0);
31744     ok(value == 24, "Got unexpected value %u.\n", value);
31745     release_resource_readback(&rb);
31746 
31747     ID3D12DescriptorHeap_Release(cpu_heap);
31748     ID3D12DescriptorHeap_Release(gpu_heap);
31749     for (i = 0; i < ARRAY_SIZE(graphics_lists); ++i)
31750         ID3D12GraphicsCommandList_Release(graphics_lists[i]);
31751     for (i = 0; i < ARRAY_SIZE(compute_lists); ++i)
31752         ID3D12GraphicsCommandList_Release(compute_lists[i]);
31753     for (i = 0; i < ARRAY_SIZE(allocators); ++i)
31754         ID3D12CommandAllocator_Release(allocators[i]);
31755     ID3D12Fence_Release(fence);
31756     ID3D12Fence_Release(fence2);
31757     ID3D12Resource_Release(buffer);
31758     ID3D12CommandQueue_Release(compute_queue);
31759     ID3D12PipelineState_Release(compute_pipeline_state);
31760     destroy_test_context(&context);
31761 }
31762 
test_early_depth_stencil_tests(void)31763 static void test_early_depth_stencil_tests(void)
31764 {
31765     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
31766     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
31767     ID3D12DescriptorHeap *cpu_heap, *gpu_heap;
31768     ID3D12GraphicsCommandList *command_list;
31769     D3D12_DESCRIPTOR_RANGE descriptor_range;
31770     D3D12_ROOT_PARAMETER root_parameter;
31771     struct depth_stencil_resource ds;
31772     struct test_context_desc desc;
31773     struct test_context context;
31774     ID3D12CommandQueue *queue;
31775     ID3D12Resource *texture;
31776     HRESULT hr;
31777 
31778     static const DWORD ps_code[] =
31779     {
31780 #if 0
31781         RWTexture2D<int> u;
31782 
31783         [earlydepthstencil]
31784         void main()
31785         {
31786             InterlockedAdd(u[uint2(0, 0)], 1);
31787         }
31788 #endif
31789         0x43425844, 0xd8c9f845, 0xadb9dbe2, 0x4e8aea86, 0x80f0b053, 0x00000001, 0x0000009c, 0x00000003,
31790         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
31791         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000048, 0x00000050, 0x00000012, 0x0100286a,
31792         0x0400189c, 0x0011e000, 0x00000000, 0x00003333, 0x0a0000ad, 0x0011e000, 0x00000000, 0x00004002,
31793         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004001, 0x00000001, 0x0100003e,
31794     };
31795     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
31796     static const UINT values[4] = {0};
31797 
31798     memset(&desc, 0, sizeof(desc));
31799     desc.no_render_target = true;
31800     if (!init_test_context(&context, &desc))
31801         return;
31802     command_list = context.list;
31803     queue = context.queue;
31804 
31805     descriptor_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
31806     descriptor_range.NumDescriptors = 1;
31807     descriptor_range.BaseShaderRegister = 0;
31808     descriptor_range.RegisterSpace = 0;
31809     descriptor_range.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
31810     root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
31811     root_parameter.DescriptorTable.NumDescriptorRanges = 1;
31812     root_parameter.DescriptorTable.pDescriptorRanges = &descriptor_range;
31813     root_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
31814     root_signature_desc.NumParameters = 1;
31815     root_signature_desc.pParameters = &root_parameter;
31816     root_signature_desc.NumStaticSamplers = 0;
31817     root_signature_desc.pStaticSamplers = NULL;
31818     root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
31819     hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
31820     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
31821 
31822     init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, &ps, NULL);
31823     pso_desc.NumRenderTargets = 0;
31824     pso_desc.DSVFormat = DXGI_FORMAT_D32_FLOAT;
31825     pso_desc.DepthStencilState.DepthEnable = true;
31826     pso_desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
31827     pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;
31828     hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
31829             &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
31830     ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
31831 
31832     init_depth_stencil(&ds, context.device, 1, 1, 1, 1, DXGI_FORMAT_D32_FLOAT, 0, NULL);
31833     set_rect(&context.scissor_rect, 0, 0, 1, 1);
31834 
31835     texture = create_default_texture(context.device, 1, 1, DXGI_FORMAT_R32_SINT,
31836             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
31837     cpu_heap = create_cpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
31838     gpu_heap = create_gpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
31839     ID3D12Device_CreateUnorderedAccessView(context.device, texture, NULL, NULL,
31840             get_cpu_descriptor_handle(&context, cpu_heap, 0));
31841     ID3D12Device_CreateUnorderedAccessView(context.device, texture, NULL, NULL,
31842             get_cpu_descriptor_handle(&context, gpu_heap, 0));
31843 
31844     set_viewport(&context.viewport, 0.0f, 0.0f, 1.0f, 100.0f, 0.5f, 0.5f);
31845 
31846     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, NULL, false, &ds.dsv_handle);
31847     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
31848     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
31849     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
31850     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
31851     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
31852     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &gpu_heap);
31853     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
31854             get_gpu_descriptor_handle(&context, gpu_heap, 0));
31855 
31856     ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint(command_list,
31857             get_gpu_descriptor_handle(&context, gpu_heap, 0),
31858             get_cpu_descriptor_handle(&context, cpu_heap, 0), texture, values, 0, NULL);
31859 
31860     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
31861             D3D12_CLEAR_FLAG_DEPTH, 0.6f, 0, 0, NULL);
31862     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
31863     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
31864 
31865     transition_resource_state(command_list, ds.texture,
31866             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
31867     transition_resource_state(command_list, texture,
31868             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
31869     check_sub_resource_float(ds.texture, 0, queue, command_list, 0.6f, 1);
31870     reset_command_list(command_list, context.allocator);
31871     check_sub_resource_uint(texture, 0, queue, command_list, 2, 1);
31872 
31873     reset_command_list(command_list, context.allocator);
31874     transition_resource_state(command_list, ds.texture,
31875             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE);
31876     transition_resource_state(command_list, texture,
31877             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
31878     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 0, NULL, false, &ds.dsv_handle);
31879     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
31880     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
31881     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
31882     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
31883     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
31884     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &gpu_heap);
31885     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0,
31886             get_gpu_descriptor_handle(&context, gpu_heap, 0));
31887 
31888     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
31889             D3D12_CLEAR_FLAG_DEPTH, 0.3f, 0, 0, NULL);
31890     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
31891     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
31892 
31893     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
31894             D3D12_CLEAR_FLAG_DEPTH, 0.55f, 0, 0, NULL);
31895     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
31896 
31897     ID3D12GraphicsCommandList_ClearDepthStencilView(command_list, ds.dsv_handle,
31898             D3D12_CLEAR_FLAG_DEPTH, 0.5f, 0, 0, NULL);
31899     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
31900 
31901     transition_resource_state(command_list, ds.texture,
31902             D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE);
31903     transition_resource_state(command_list, texture,
31904             D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
31905     check_sub_resource_float(ds.texture, 0, queue, command_list, 0.5f, 1);
31906     reset_command_list(command_list, context.allocator);
31907     check_sub_resource_uint(texture, 0, queue, command_list, 4, 1);
31908 
31909     ID3D12Resource_Release(texture);
31910     ID3D12DescriptorHeap_Release(cpu_heap);
31911     ID3D12DescriptorHeap_Release(gpu_heap);
31912     destroy_depth_stencil(&ds);
31913     destroy_test_context(&context);
31914 }
31915 
prepare_instanced_draw(struct test_context * context)31916 static void prepare_instanced_draw(struct test_context *context)
31917 {
31918     ID3D12GraphicsCommandList *command_list = context->list;
31919 
31920     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context->rtv, false, NULL);
31921     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context->root_signature);
31922     ID3D12GraphicsCommandList_SetPipelineState(command_list, context->pipeline_state);
31923     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
31924     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context->viewport);
31925     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context->scissor_rect);
31926 }
31927 
test_conditional_rendering(void)31928 static void test_conditional_rendering(void)
31929 {
31930     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
31931     ID3D12Resource *conditions, *upload_buffer;
31932     ID3D12CommandSignature *command_signature;
31933     ID3D12GraphicsCommandList *command_list;
31934     D3D12_ROOT_PARAMETER root_parameters[2];
31935     ID3D12Resource *texture, *texture_copy;
31936     D3D12_RENDER_TARGET_VIEW_DESC rtv_desc;
31937     D3D12_HEAP_PROPERTIES heap_properties;
31938     ID3D12PipelineState *pipeline_state;
31939     ID3D12RootSignature *root_signature;
31940     D3D12_RESOURCE_DESC resource_desc;
31941     struct test_context context;
31942     ID3D12Resource *buffer, *cb;
31943     struct resource_readback rb;
31944     ID3D12CommandQueue *queue;
31945     unsigned int i;
31946     uint32_t value;
31947     HRESULT hr;
31948 
31949     static const uint64_t predicate_args[] = {0, 1, (uint64_t)1 << 32};
31950     static const uint32_t r8g8b8a8_data[] = {0x28384858, 0x39495969};
31951     static const D3D12_DRAW_ARGUMENTS draw_args = {3, 1, 0, 0};
31952     static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
31953     static const float green[] = {0.0f, 1.0f, 0.0f, 1.0f};
31954     static const float ms_color[] = {0.345f, 0.282f, 0.219f, 0.156f};
31955     static const uint32_t init_value = 0xdeadbeef;
31956     static const D3D12_SUBRESOURCE_DATA copy_data[] =
31957     {
31958         {&r8g8b8a8_data[0], sizeof(r8g8b8a8_data[0]), sizeof(r8g8b8a8_data[0])},
31959         {&r8g8b8a8_data[1], sizeof(r8g8b8a8_data[1]), sizeof(r8g8b8a8_data[1])}
31960     };
31961     static const DWORD cs_code[] =
31962     {
31963 #if 0
31964         cbuffer cb
31965         {
31966             unsigned int offset;
31967             unsigned int value;
31968         };
31969 
31970         RWByteAddressBuffer b;
31971 
31972         [numthreads(1, 1, 1)]
31973         void main()
31974         {
31975             b.Store(4 * offset, value);
31976         }
31977 #endif
31978         0x43425844, 0xaadc5460, 0x88c27e90, 0x2acacf4e, 0x4e06019a, 0x00000001, 0x000000d8, 0x00000003,
31979         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
31980         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000084, 0x00050050, 0x00000021, 0x0100086a,
31981         0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x0300009d, 0x0011e000, 0x00000000, 0x02000068,
31982         0x00000001, 0x0400009b, 0x00000001, 0x00000001, 0x00000001, 0x08000029, 0x00100012, 0x00000000,
31983         0x0020800a, 0x00000000, 0x00000000, 0x00004001, 0x00000002, 0x080000a6, 0x0011e012, 0x00000000,
31984         0x0010000a, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x0100003e,
31985     };
31986     static const struct
31987     {
31988         uint32_t offset;
31989         uint32_t value;
31990         uint32_t uav_offset;
31991     }
31992     input = {0, 4, 0};
31993 
31994     if (!init_test_context(&context, NULL))
31995         return;
31996     command_list = context.list;
31997     queue = context.queue;
31998 
31999     if (is_intel_windows_device(context.device))
32000     {
32001         skip("Predicated rendering is broken on Intel.\n");
32002         destroy_test_context(&context);
32003         return;
32004     }
32005 
32006     conditions = create_default_buffer(context.device, sizeof(predicate_args),
32007             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
32008     upload_buffer_data(conditions, 0, sizeof(predicate_args), &predicate_args, queue, command_list);
32009     reset_command_list(command_list, context.allocator);
32010     transition_resource_state(command_list, conditions,
32011             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PREDICATION);
32012 
32013     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
32014 
32015     /* Skip draw on zero. */
32016     prepare_instanced_draw(&context);
32017     ID3D12GraphicsCommandList_SetPredication(command_list, conditions, 0, D3D12_PREDICATION_OP_EQUAL_ZERO);
32018     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
32019     ID3D12GraphicsCommandList_SetPredication(command_list, NULL, 0, 0);
32020 
32021     transition_resource_state(command_list, context.render_target,
32022             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
32023 
32024     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xffffffff, 0);
32025 
32026     reset_command_list(command_list, context.allocator);
32027     transition_resource_state(command_list, context.render_target,
32028             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
32029 
32030     /* Skip draw on non-zero. */
32031     prepare_instanced_draw(&context);
32032     ID3D12GraphicsCommandList_SetPredication(command_list, conditions,
32033             sizeof(uint64_t), D3D12_PREDICATION_OP_NOT_EQUAL_ZERO);
32034     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
32035     /* Don't reset predication to test automatic reset on next SetPredication() call. */
32036 
32037     transition_resource_state(command_list, context.render_target,
32038             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
32039 
32040     ID3D12GraphicsCommandList_SetPredication(command_list, conditions,
32041             sizeof(uint64_t), D3D12_PREDICATION_OP_EQUAL_ZERO);
32042     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xffffffff, 0);
32043 
32044     reset_command_list(command_list, context.allocator);
32045     transition_resource_state(command_list, context.render_target,
32046             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
32047 
32048     /* Skip clear on zero. */
32049     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
32050     ID3D12GraphicsCommandList_SetPredication(command_list, conditions, 0, D3D12_PREDICATION_OP_EQUAL_ZERO);
32051     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, green, 0, NULL);
32052     ID3D12GraphicsCommandList_SetPredication(command_list, NULL, 0, 0);
32053 
32054     transition_resource_state(command_list, context.render_target,
32055             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
32056 
32057     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
32058     bug_if(is_radv_device(context.device))
32059     todo check_readback_data_uint(&rb, NULL, 0xffffffff, 0);
32060     release_resource_readback(&rb);
32061 
32062     reset_command_list(command_list, context.allocator);
32063     transition_resource_state(command_list, context.render_target,
32064             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
32065 
32066     /* Draw on zero. */
32067     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
32068     prepare_instanced_draw(&context);
32069     ID3D12GraphicsCommandList_SetPredication(command_list, conditions, 0, D3D12_PREDICATION_OP_NOT_EQUAL_ZERO);
32070     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
32071     ID3D12GraphicsCommandList_SetPredication(command_list, NULL, 0, 0);
32072 
32073     transition_resource_state(command_list, context.render_target,
32074             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
32075 
32076     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
32077 
32078     reset_command_list(command_list, context.allocator);
32079     transition_resource_state(command_list, context.render_target,
32080             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
32081 
32082     /* Draw on non-zero. */
32083     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
32084     prepare_instanced_draw(&context);
32085     ID3D12GraphicsCommandList_SetPredication(command_list, conditions,
32086             sizeof(uint64_t), D3D12_PREDICATION_OP_EQUAL_ZERO);
32087     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
32088     ID3D12GraphicsCommandList_SetPredication(command_list, NULL, 0, 0);
32089 
32090     transition_resource_state(command_list, context.render_target,
32091             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
32092 
32093     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
32094 
32095     reset_command_list(command_list, context.allocator);
32096     transition_resource_state(command_list, context.render_target,
32097             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
32098 
32099     /* 64-bit conditional 0x100000000 - fails due to Vulkan 32-bit values. */
32100     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
32101     prepare_instanced_draw(&context);
32102     ID3D12GraphicsCommandList_SetPredication(command_list, conditions,
32103             2 * sizeof(uint64_t), D3D12_PREDICATION_OP_NOT_EQUAL_ZERO);
32104     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
32105     ID3D12GraphicsCommandList_SetPredication(command_list, NULL, 0, 0);
32106 
32107     transition_resource_state(command_list, context.render_target,
32108             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
32109 
32110     get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
32111     todo check_readback_data_uint(&rb, NULL, 0xffffffff, 0);
32112     release_resource_readback(&rb);
32113     reset_command_list(command_list, context.allocator);
32114     transition_resource_state(command_list, context.render_target,
32115             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
32116 
32117     /* Direct3D latches the value of the predicate upon beginning predicated rendering. */
32118     buffer = create_default_buffer(context.device, sizeof(predicate_args),
32119             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
32120     transition_resource_state(command_list, conditions,
32121             D3D12_RESOURCE_STATE_PREDICATION, D3D12_RESOURCE_STATE_COPY_SOURCE);
32122     ID3D12GraphicsCommandList_CopyResource(command_list, buffer, conditions);
32123     transition_resource_state(command_list,
32124             buffer, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PREDICATION);
32125 
32126     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
32127     prepare_instanced_draw(&context);
32128     ID3D12GraphicsCommandList_SetPredication(command_list, buffer, 0, D3D12_PREDICATION_OP_NOT_EQUAL_ZERO);
32129 
32130     transition_resource_state(command_list, buffer,
32131             D3D12_RESOURCE_STATE_PREDICATION, D3D12_RESOURCE_STATE_COPY_DEST);
32132     ID3D12GraphicsCommandList_CopyBufferRegion(command_list, buffer, 0, conditions, sizeof(uint64_t), sizeof(uint64_t));
32133     transition_resource_state(command_list,
32134             buffer, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PREDICATION);
32135     transition_resource_state(command_list,
32136             conditions, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_PREDICATION);
32137 
32138     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
32139     ID3D12GraphicsCommandList_SetPredication(command_list, NULL, 0, 0);
32140 
32141     transition_resource_state(command_list, context.render_target,
32142             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
32143     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
32144 
32145     ID3D12Resource_Release(buffer);
32146     reset_command_list(command_list, context.allocator);
32147     transition_resource_state(command_list, context.render_target,
32148             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
32149 
32150     /* SetPredication() and upload buffer. */
32151     upload_buffer = create_upload_buffer(context.device, sizeof(predicate_args), predicate_args);
32152 
32153     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
32154     prepare_instanced_draw(&context);
32155     /* Skip. */
32156     ID3D12GraphicsCommandList_SetPredication(command_list, upload_buffer,
32157             0, D3D12_PREDICATION_OP_EQUAL_ZERO);
32158     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
32159 
32160     ID3D12GraphicsCommandList_SetPredication(command_list, upload_buffer,
32161             0, D3D12_PREDICATION_OP_NOT_EQUAL_ZERO);
32162     transition_resource_state(command_list, context.render_target,
32163             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
32164     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xffffffff, 0);
32165 
32166     reset_command_list(command_list, context.allocator);
32167     transition_resource_state(command_list, context.render_target,
32168             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
32169 
32170     /* ExecuteIndirect(). */
32171     buffer = create_upload_buffer(context.device, sizeof(draw_args), &draw_args);
32172 
32173     command_signature = create_command_signature(context.device, D3D12_INDIRECT_ARGUMENT_TYPE_DRAW);
32174 
32175     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
32176     prepare_instanced_draw(&context);
32177     /* Skip. */
32178     ID3D12GraphicsCommandList_SetPredication(command_list, conditions, 0, D3D12_PREDICATION_OP_EQUAL_ZERO);
32179     ID3D12GraphicsCommandList_ExecuteIndirect(command_list, command_signature, 1, buffer, 0, NULL, 0);
32180     ID3D12GraphicsCommandList_SetPredication(command_list, NULL, 0, 0);
32181 
32182     transition_resource_state(command_list, context.render_target,
32183             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
32184 
32185     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xffffffff, 0);
32186 
32187     reset_command_list(command_list, context.allocator);
32188     transition_resource_state(command_list, context.render_target,
32189             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
32190 
32191     prepare_instanced_draw(&context);
32192     /* Draw. */
32193     ID3D12GraphicsCommandList_SetPredication(command_list, conditions, 0, D3D12_PREDICATION_OP_NOT_EQUAL_ZERO);
32194     ID3D12GraphicsCommandList_ExecuteIndirect(command_list, command_signature, 1, buffer, 0, NULL, 0);
32195     ID3D12GraphicsCommandList_SetPredication(command_list, NULL, 0, 0);
32196 
32197     transition_resource_state(command_list, context.render_target,
32198             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
32199 
32200     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
32201 
32202     ID3D12Resource_Release(buffer);
32203     ID3D12CommandSignature_Release(command_signature);
32204     reset_command_list(command_list, context.allocator);
32205 
32206     /* CopyResource(). */
32207     texture = create_default_texture(context.device,
32208             1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D12_RESOURCE_STATE_COPY_DEST);
32209     upload_texture_data(texture, &copy_data[0], 1, queue, command_list);
32210     reset_command_list(command_list, context.allocator);
32211     transition_resource_state(command_list, texture,
32212             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
32213 
32214     texture_copy = create_default_texture(context.device,
32215                 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D12_RESOURCE_STATE_COPY_DEST);
32216     upload_texture_data(texture_copy, &copy_data[1], 1, queue, command_list);
32217     reset_command_list(command_list, context.allocator);
32218 
32219     /* Skip. */
32220     ID3D12GraphicsCommandList_SetPredication(command_list, conditions, 0, D3D12_PREDICATION_OP_EQUAL_ZERO);
32221     ID3D12GraphicsCommandList_CopyResource(command_list, texture_copy, texture);
32222     ID3D12GraphicsCommandList_SetPredication(command_list, NULL, 0, 0);
32223 
32224     transition_resource_state(command_list, texture_copy,
32225             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
32226 
32227     get_texture_readback_with_command_list(texture_copy, 0, &rb, queue, command_list);
32228     todo check_readback_data_uint(&rb, NULL, r8g8b8a8_data[1], 0);
32229     release_resource_readback(&rb);
32230 
32231     reset_command_list(command_list, context.allocator);
32232     transition_resource_state(command_list, texture_copy,
32233             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_COPY_DEST);
32234 
32235     /* Copy. */
32236     ID3D12GraphicsCommandList_SetPredication(command_list, conditions, 0, D3D12_PREDICATION_OP_NOT_EQUAL_ZERO);
32237     ID3D12GraphicsCommandList_CopyResource(command_list, texture_copy, texture);
32238     ID3D12GraphicsCommandList_SetPredication(command_list, NULL, 0, 0);
32239 
32240     transition_resource_state(command_list, texture_copy,
32241             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
32242 
32243     check_sub_resource_uint(texture_copy, 0, queue, command_list, r8g8b8a8_data[0], 0);
32244 
32245     /* Multisample texture. */
32246     ID3D12Resource_Release(texture);
32247     memset(&heap_properties, 0, sizeof(heap_properties));
32248     heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
32249 
32250     memset(&resource_desc, 0, sizeof(resource_desc));
32251     resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
32252     resource_desc.Width = 1;
32253     resource_desc.Height = 1;
32254     resource_desc.DepthOrArraySize = 1;
32255     resource_desc.MipLevels = 1;
32256     resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
32257     resource_desc.SampleDesc.Count = 4;
32258     resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
32259     hr = ID3D12Device_CreateCommittedResource(context.device, &heap_properties, D3D12_HEAP_FLAG_NONE,
32260             &resource_desc, D3D12_RESOURCE_STATE_RENDER_TARGET, NULL, &IID_ID3D12Resource, (void **)&texture);
32261     ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
32262 
32263     memset(&rtv_desc, 0, sizeof(rtv_desc));
32264     rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS;
32265     rtv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
32266     ID3D12Device_CreateRenderTargetView(context.device, texture, &rtv_desc,
32267             get_cpu_rtv_handle(&context, context.rtv_heap, 0));
32268 
32269     reset_command_list(command_list, context.allocator);
32270     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, ms_color, 0, NULL);
32271 
32272     /* ResolveSubresource(). */
32273     transition_resource_state(command_list, texture_copy,
32274             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_COPY_DEST);
32275     upload_texture_data(texture_copy, &copy_data[1], 1, queue, command_list);
32276 
32277     reset_command_list(command_list, context.allocator);
32278     transition_resource_state(command_list, texture_copy,
32279             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_RESOLVE_DEST);
32280     transition_resource_state(command_list, texture,
32281             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
32282 
32283     /* Skip. */
32284     ID3D12GraphicsCommandList_SetPredication(command_list, conditions, 0, D3D12_PREDICATION_OP_EQUAL_ZERO);
32285     ID3D12GraphicsCommandList_ResolveSubresource(command_list,
32286             texture_copy, 0, texture, 0, DXGI_FORMAT_R8G8B8A8_UNORM);
32287     ID3D12GraphicsCommandList_SetPredication(command_list, NULL, 0, 0);
32288 
32289     transition_resource_state(command_list, texture_copy,
32290             D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
32291 
32292     get_texture_readback_with_command_list(texture_copy, 0, &rb, queue, command_list);
32293     bug_if(is_radv_device(context.device))
32294     todo check_readback_data_uint(&rb, NULL, r8g8b8a8_data[1], 0);
32295     release_resource_readback(&rb);
32296 
32297     reset_command_list(command_list, context.allocator);
32298     transition_resource_state(command_list, texture_copy,
32299             D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RESOLVE_DEST);
32300 
32301     /* Resolve. */
32302     ID3D12GraphicsCommandList_SetPredication(command_list, conditions, 0, D3D12_PREDICATION_OP_NOT_EQUAL_ZERO);
32303     ID3D12GraphicsCommandList_ResolveSubresource(command_list,
32304             texture_copy, 0, texture, 0, DXGI_FORMAT_R8G8B8A8_UNORM);
32305     ID3D12GraphicsCommandList_SetPredication(command_list, NULL, 0, 0);
32306 
32307     transition_resource_state(command_list, texture_copy,
32308             D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_COPY_SOURCE);
32309 
32310     check_sub_resource_uint(texture_copy, 0, queue, command_list, r8g8b8a8_data[0], 2);
32311 
32312     reset_command_list(command_list, context.allocator);
32313 
32314     /* Dispatch(). */
32315     cb = create_upload_buffer(context.device, sizeof(input), &input);
32316 
32317     buffer = create_default_buffer(context.device, 512,
32318             D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
32319     upload_buffer_data(buffer, 0, sizeof(init_value), &init_value, queue, command_list);
32320     reset_command_list(command_list, context.allocator);
32321     transition_sub_resource_state(command_list, buffer, 0,
32322             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
32323 
32324     root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
32325     root_parameters[0].Descriptor.ShaderRegister = 0;
32326     root_parameters[0].Descriptor.RegisterSpace = 0;
32327     root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
32328     root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
32329     root_parameters[1].Descriptor.ShaderRegister = 0;
32330     root_parameters[1].Descriptor.RegisterSpace = 0;
32331     root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
32332     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
32333     root_signature_desc.NumParameters = 2;
32334     root_signature_desc.pParameters = root_parameters;
32335     hr = create_root_signature(context.device, &root_signature_desc, &root_signature);
32336     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
32337 
32338     pipeline_state = create_compute_pipeline_state(context.device, root_signature,
32339             shader_bytecode(cs_code, sizeof(cs_code)));
32340 
32341     for (i = 0; i < 2; ++i)
32342     {
32343         ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
32344         ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, root_signature);
32345         ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(command_list,
32346                 0, ID3D12Resource_GetGPUVirtualAddress(cb));
32347         ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list,
32348                 1, ID3D12Resource_GetGPUVirtualAddress(buffer));
32349         ID3D12GraphicsCommandList_SetPredication(command_list, conditions, i * sizeof(uint64_t),
32350                 D3D12_PREDICATION_OP_EQUAL_ZERO);
32351         ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
32352         ID3D12GraphicsCommandList_SetPredication(command_list, NULL, 0, 0);
32353 
32354         transition_sub_resource_state(command_list, buffer, 0,
32355                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
32356 
32357         get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
32358         value = get_readback_uint(&rb, 0, 0, 0);
32359         ok(value == (!i ? init_value : input.value), "Got %#x, expected %#x.\n", value, input.value);
32360         release_resource_readback(&rb);
32361         reset_command_list(command_list, context.allocator);
32362 
32363         transition_sub_resource_state(command_list, buffer, 0,
32364                 D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
32365     }
32366 
32367     ID3D12Resource_Release(texture);
32368     ID3D12Resource_Release(texture_copy);
32369     ID3D12Resource_Release(conditions);
32370     ID3D12Resource_Release(cb);
32371     ID3D12Resource_Release(buffer);
32372     ID3D12Resource_Release(upload_buffer);
32373     ID3D12RootSignature_Release(root_signature);
32374     ID3D12PipelineState_Release(pipeline_state);
32375     destroy_test_context(&context);
32376 }
test_bufinfo_instruction(void)32377 static void test_bufinfo_instruction(void)
32378 {
32379     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
32380     D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
32381     const D3D12_SHADER_BYTECODE *current_shader;
32382     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
32383     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
32384     ID3D12GraphicsCommandList *command_list;
32385     D3D12_DESCRIPTOR_RANGE descriptor_range;
32386     D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle;
32387     D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle;
32388     D3D12_INPUT_LAYOUT_DESC input_layout;
32389     D3D12_ROOT_PARAMETER root_parameter;
32390     struct test_context_desc desc;
32391     D3D12_VERTEX_BUFFER_VIEW vbv;
32392     struct test_context context;
32393     ID3D12Resource *vb, *buffer;
32394     ID3D12DescriptorHeap *heap;
32395     ID3D12CommandQueue *queue;
32396     ID3D12Device *device;
32397     HRESULT hr;
32398     int i;
32399     static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
32400     {
32401         {"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
32402     };
32403     static const DWORD vs_code[] =
32404     {
32405 #if 0
32406         void main(float4 in_position : POSITION, out float4 out_position : SV_POSITION)
32407         {
32408             out_position = in_position;
32409         }
32410 #endif
32411         0x43425844, 0xa7a2f22d, 0x83ff2560, 0xe61638bd, 0x87e3ce90, 0x00000001, 0x000000d8, 0x00000003,
32412         0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
32413         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
32414         0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
32415         0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040,
32416         0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
32417         0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
32418     };
32419     static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
32420     static const DWORD ps_srv_raw_code[] =
32421     {
32422 #if 0
32423         ByteAddressBuffer b;
32424 
32425         uint4 main(void) : SV_Target
32426         {
32427             uint width;
32428             b.GetDimensions(width);
32429             return width;
32430         }
32431 #endif
32432         0x43425844, 0x934bc27a, 0x3251cc9d, 0xa129bdd3, 0xf7cedcc4, 0x00000001, 0x000000d8, 0x00000003,
32433         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
32434         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
32435         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000060, 0x00000050, 0x00000018,
32436         0x0100086a, 0x030000a1, 0x00107000, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
32437         0x00000001, 0x87000079, 0x800002c2, 0x00199983, 0x00100012, 0x00000000, 0x00107e46, 0x00000000,
32438         0x05000036, 0x001020f2, 0x00000000, 0x00100006, 0x00000000, 0x0100003e,
32439     };
32440     static const D3D12_SHADER_BYTECODE ps_srv_raw = {ps_srv_raw_code, sizeof(ps_srv_raw_code)};
32441     static const DWORD ps_srv_structured_code[] =
32442     {
32443 #if 0
32444         StructuredBuffer<bool> b;
32445 
32446         uint4 main(void) : SV_Target
32447         {
32448             uint count, stride;
32449             b.GetDimensions(count, stride);
32450             return uint4(count, stride, 0, 1);
32451         }
32452 #endif
32453         0x43425844, 0x313f910c, 0x2f60c646, 0x2d87455c, 0xb9988c2c, 0x00000001, 0x000000fc, 0x00000003,
32454         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
32455         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
32456         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000084, 0x00000050, 0x00000021,
32457         0x0100086a, 0x040000a2, 0x00107000, 0x00000000, 0x00000004, 0x03000065, 0x001020f2, 0x00000000,
32458         0x02000068, 0x00000001, 0x87000079, 0x80002302, 0x00199983, 0x00100012, 0x00000000, 0x00107e46,
32459         0x00000000, 0x05000036, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x08000036, 0x001020e2,
32460         0x00000000, 0x00004002, 0x00000000, 0x00000004, 0x00000000, 0x00000001, 0x0100003e,
32461     };
32462     static const D3D12_SHADER_BYTECODE ps_srv_structured = {ps_srv_structured_code, sizeof(ps_srv_structured_code)};
32463     static const DWORD ps_srv_typed_code[] =
32464     {
32465 #if 0
32466         Buffer<float> b;
32467 
32468         uint4 main(void) : SV_Target
32469         {
32470             uint width;
32471             b.GetDimensions(width);
32472             return width;
32473         }
32474 #endif
32475         0x43425844, 0x6ae6dbb0, 0x6289d227, 0xaf4e708e, 0x111efed1, 0x00000001, 0x000000dc, 0x00000003,
32476         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
32477         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
32478         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000064, 0x00000050, 0x00000019,
32479         0x0100086a, 0x04000858, 0x00107000, 0x00000000, 0x00005555, 0x03000065, 0x001020f2, 0x00000000,
32480         0x02000068, 0x00000001, 0x87000079, 0x80000042, 0x00155543, 0x00100012, 0x00000000, 0x00107e46,
32481         0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00100006, 0x00000000, 0x0100003e,
32482     };
32483     static const D3D12_SHADER_BYTECODE ps_srv_typed = {ps_srv_typed_code, sizeof(ps_srv_typed_code)};
32484     static const DWORD ps_uav_raw_code[] =
32485     {
32486 #if 0
32487         RWByteAddressBuffer b;
32488 
32489         uint4 main(void) : SV_Target
32490         {
32491             uint width;
32492             b.GetDimensions(width);
32493             return width;
32494         }
32495 #endif
32496         0x43425844, 0xb06e9715, 0x99733b00, 0xaa536550, 0x703a01c5, 0x00000001, 0x000000d8, 0x00000003,
32497         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
32498         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
32499         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000060, 0x00000050, 0x00000018,
32500         0x0100086a, 0x0300009d, 0x0011e000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
32501         0x00000001, 0x87000079, 0x800002c2, 0x00199983, 0x00100012, 0x00000000, 0x0011ee46, 0x00000001,
32502         0x05000036, 0x001020f2, 0x00000000, 0x00100006, 0x00000000, 0x0100003e,
32503     };
32504     static const D3D12_SHADER_BYTECODE ps_uav_raw = {ps_uav_raw_code, sizeof(ps_uav_raw_code)};
32505     static const DWORD ps_uav_structured_code[] =
32506     {
32507 #if 0
32508         struct s
32509         {
32510             uint4 u;
32511             bool b;
32512         };
32513 
32514         RWStructuredBuffer<s> b;
32515 
32516         uint4 main(void) : SV_Target
32517         {
32518             uint count, stride;
32519             b.GetDimensions(count, stride);
32520             return uint4(count, stride, 0, 1);
32521         }
32522 #endif
32523         0x43425844, 0xe1900f85, 0x13c1f338, 0xbb19865e, 0x366df28f, 0x00000001, 0x000000fc, 0x00000003,
32524         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
32525         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
32526         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000084, 0x00000050, 0x00000021,
32527         0x0100086a, 0x0400009e, 0x0011e000, 0x00000001, 0x00000014, 0x03000065, 0x001020f2, 0x00000000,
32528         0x02000068, 0x00000001, 0x87000079, 0x8000a302, 0x00199983, 0x00100012, 0x00000000, 0x0011ee46,
32529         0x00000001, 0x05000036, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x08000036, 0x001020e2,
32530         0x00000000, 0x00004002, 0x00000000, 0x00000014, 0x00000000, 0x00000001, 0x0100003e,
32531     };
32532     static const D3D12_SHADER_BYTECODE ps_uav_structured = {ps_uav_structured_code, sizeof(ps_uav_structured_code)};
32533     static const DWORD ps_uav_structured32_code[] =
32534     {
32535 #if 0
32536         struct s
32537         {
32538             uint4 u;
32539             bool4 b;
32540         };
32541 
32542         RWStructuredBuffer<s> b;
32543 
32544         uint4 main(void) : SV_Target
32545         {
32546             uint count, stride;
32547             b.GetDimensions(count, stride);
32548             return uint4(count, stride, 0, 1);
32549         }
32550 #endif
32551         0x43425844, 0xdd87a805, 0x28090470, 0xe4fa7c4d, 0x57963f52, 0x00000001, 0x000000fc, 0x00000003,
32552         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
32553         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
32554         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000084, 0x00000050, 0x00000021,
32555         0x0100086a, 0x0400009e, 0x0011e000, 0x00000001, 0x00000020, 0x03000065, 0x001020f2, 0x00000000,
32556         0x02000068, 0x00000001, 0x87000079, 0x80010302, 0x00199983, 0x00100012, 0x00000000, 0x0011ee46,
32557         0x00000001, 0x05000036, 0x00102012, 0x00000000, 0x0010000a, 0x00000000, 0x08000036, 0x001020e2,
32558         0x00000000, 0x00004002, 0x00000000, 0x00000020, 0x00000000, 0x00000001, 0x0100003e,
32559     };
32560     static const D3D12_SHADER_BYTECODE ps_uav_structured32 = {ps_uav_structured32_code, sizeof(ps_uav_structured32_code)};
32561     static const DWORD ps_uav_typed_code[] =
32562     {
32563 #if 0
32564         RWBuffer<float> b;
32565 
32566         uint4 main(void) : SV_Target
32567         {
32568             uint width;
32569             b.GetDimensions(width);
32570             return width;
32571         }
32572 #endif
32573         0x43425844, 0x96b39f5f, 0x5fef24c7, 0xed404a41, 0x01c9d4fe, 0x00000001, 0x000000dc, 0x00000003,
32574         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
32575         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
32576         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000064, 0x00000050, 0x00000019,
32577         0x0100086a, 0x0400089c, 0x0011e000, 0x00000001, 0x00005555, 0x03000065, 0x001020f2, 0x00000000,
32578         0x02000068, 0x00000001, 0x87000079, 0x80000042, 0x00155543, 0x00100012, 0x00000000, 0x0011ee46,
32579         0x00000001, 0x05000036, 0x001020f2, 0x00000000, 0x00100006, 0x00000000, 0x0100003e,
32580     };
32581     static const D3D12_SHADER_BYTECODE ps_uav_typed = {ps_uav_typed_code, sizeof(ps_uav_typed_code)};
32582     static const struct test
32583     {
32584         const D3D12_SHADER_BYTECODE *ps;
32585         BOOL uav;
32586         BOOL raw;
32587         unsigned int buffer_size;
32588         unsigned int buffer_structure_byte_stride;
32589         DXGI_FORMAT view_format;
32590         unsigned int view_element_idx;
32591         unsigned int view_element_count;
32592         struct uvec4 expected_result;
32593     }
32594     tests[] =
32595     {
32596         {&ps_srv_raw,          false, true,  100,  0, DXGI_FORMAT_R32_TYPELESS,  0, 25, {100, 100, 100, 100}},
32597         {&ps_srv_raw,          false, true,  500,  0, DXGI_FORMAT_R32_TYPELESS, 64,  4, { 16,  16,  16,  16}},
32598         {&ps_srv_structured,   false, false, 100,  4, DXGI_FORMAT_UNKNOWN,       0,  5, {  5,   4,   0,   1}},
32599         {&ps_srv_structured,   false, false, 100,  4, DXGI_FORMAT_UNKNOWN,       0,  2, {  2,   4,   0,   1}},
32600         {&ps_srv_structured,   false, false, 400,  4, DXGI_FORMAT_UNKNOWN,      64,  2, {  2,   4,   0,   1}},
32601         {&ps_srv_typed,        false, false, 200,  0, DXGI_FORMAT_R32_FLOAT,     0, 50, { 50,  50,  50,  50}},
32602         {&ps_srv_typed,        false, false, 400,  0, DXGI_FORMAT_R32_FLOAT,    64,  1, {  1,   1,   1,   1}},
32603         {&ps_srv_typed,        false, false, 100,  0, DXGI_FORMAT_R16_FLOAT,     0, 50, { 50,  50,  50,  50}},
32604         {&ps_srv_typed,        false, false, 400,  0, DXGI_FORMAT_R16_FLOAT,   128,  2, {  2,   2,   2,   2}},
32605         {&ps_uav_raw,          true,  true,  100,  0, DXGI_FORMAT_R32_TYPELESS,  0, 25, {100, 100, 100, 100}},
32606         {&ps_uav_raw,          true,  true,  512,  0, DXGI_FORMAT_R32_TYPELESS, 64, 64, {256, 256, 256, 256}},
32607         {&ps_uav_structured,   true,  false, 100, 20, DXGI_FORMAT_UNKNOWN,       0,  5, {  5,  20,   0,   1}},
32608         {&ps_uav_structured,   true,  false, 100, 20, DXGI_FORMAT_UNKNOWN,       0,  2, {  2,  20,   0,   1}},
32609         {&ps_uav_structured32, true,  false, 320, 32, DXGI_FORMAT_UNKNOWN,       8,  2, {  2,  32,   0,   1}},
32610         {&ps_uav_typed,        true,  false, 200,  0, DXGI_FORMAT_R32_FLOAT,     0, 50, { 50,  50,  50,  50}},
32611         {&ps_uav_typed,        true,  false, 400,  0, DXGI_FORMAT_R32_FLOAT,    64,  1, {  1,   1,   1,   1}},
32612         {&ps_uav_typed,        true,  false, 100,  0, DXGI_FORMAT_R16_FLOAT,     0, 50, { 50,  50,  50,  50}},
32613         {&ps_uav_typed,        true,  false, 400,  0, DXGI_FORMAT_R16_FLOAT,   128,  1, {  1,   1,   1,   1}},
32614     };
32615     static const struct vec4 quad[] =
32616     {
32617         {-1.0f, -1.0f, 0.0f, 1.0f},
32618         {-1.0f,  1.0f, 0.0f, 1.0f},
32619         { 1.0f, -1.0f, 0.0f, 1.0f},
32620         { 1.0f,  1.0f, 0.0f, 1.0f},
32621     };
32622 
32623     memset(&desc, 0, sizeof(desc));
32624     desc.rt_width = desc.rt_height = 64;
32625     desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
32626     desc.no_root_signature = true;
32627     desc.no_pipeline = true;
32628     if (!init_test_context(&context, &desc))
32629         return;
32630     device = context.device;
32631     command_list = context.list;
32632     queue = context.queue;
32633 
32634     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
32635     cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
32636     gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
32637 
32638     vb = create_upload_buffer(device, sizeof(quad), quad);
32639     vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
32640     vbv.StrideInBytes = sizeof(*quad);
32641     vbv.SizeInBytes = sizeof(quad);
32642 
32643     current_shader = NULL;
32644     for (i = 0; i < ARRAY_SIZE(tests); ++i)
32645     {
32646         const struct test *test = &tests[i];
32647 
32648         vkd3d_test_set_context("Test %u", i);
32649 
32650         if (!context.root_signature || test->uav != tests[i - 1].uav)
32651         {
32652             if (context.root_signature)
32653                 ID3D12RootSignature_Release(context.root_signature);
32654 
32655             descriptor_range.RangeType = test->uav
32656                     ? D3D12_DESCRIPTOR_RANGE_TYPE_UAV : D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
32657             descriptor_range.NumDescriptors = 1;
32658             descriptor_range.BaseShaderRegister = test->uav ? 1 : 0;
32659             descriptor_range.RegisterSpace = 0;
32660             descriptor_range.OffsetInDescriptorsFromTableStart = 0;
32661             root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
32662             root_parameter.DescriptorTable.NumDescriptorRanges = 1;
32663             root_parameter.DescriptorTable.pDescriptorRanges = &descriptor_range;
32664             root_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
32665             memset(&root_signature_desc, 0, sizeof(root_signature_desc));
32666             root_signature_desc.NumParameters = 1;
32667             root_signature_desc.pParameters = &root_parameter;
32668             root_signature_desc.NumStaticSamplers = 0;
32669             root_signature_desc.pStaticSamplers = NULL;
32670             root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
32671             hr = create_root_signature(context.device, &root_signature_desc, &context.root_signature);
32672             ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
32673         }
32674 
32675         if (current_shader != test->ps)
32676         {
32677             if (context.pipeline_state)
32678                 ID3D12PipelineState_Release(context.pipeline_state);
32679 
32680             input_layout.pInputElementDescs = layout_desc;
32681             input_layout.NumElements = ARRAY_SIZE(layout_desc);
32682             current_shader = test->ps;
32683             init_pipeline_state_desc(&pso_desc, context.root_signature,
32684                     context.render_target_desc.Format, &vs, current_shader, &input_layout);
32685             hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
32686                     &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
32687             ok(hr == S_OK, "Failed to create state, hr %#x.\n", hr);
32688         }
32689 
32690         if (test->uav)
32691         {
32692             buffer = create_default_buffer(device, test->buffer_size,
32693                     D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
32694             memset(&uav_desc, 0, sizeof(uav_desc));
32695             uav_desc.Format = test->view_format;
32696             uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
32697             uav_desc.Buffer.Flags = test->raw ? D3D12_BUFFER_UAV_FLAG_RAW : 0;
32698             uav_desc.Buffer.FirstElement = test->view_element_idx;
32699             uav_desc.Buffer.NumElements = test->view_element_count;
32700             uav_desc.Buffer.StructureByteStride = test->buffer_structure_byte_stride;;
32701             ID3D12Device_CreateUnorderedAccessView(device, buffer, NULL, &uav_desc, cpu_handle);
32702         }
32703         else
32704         {
32705             buffer = create_default_buffer(device, test->buffer_size,
32706                     D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
32707             memset(&srv_desc, 0, sizeof(srv_desc));
32708             srv_desc.Format = test->view_format;
32709             srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
32710             srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
32711             srv_desc.Buffer.Flags = test->raw ? D3D12_BUFFER_SRV_FLAG_RAW : 0;
32712             srv_desc.Buffer.FirstElement = test->view_element_idx;
32713             srv_desc.Buffer.NumElements = test->view_element_count;
32714             srv_desc.Buffer.StructureByteStride = test->buffer_structure_byte_stride;
32715             ID3D12Device_CreateShaderResourceView(device, buffer, &srv_desc, cpu_handle);
32716         }
32717 
32718         ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
32719         ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
32720         ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
32721         ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
32722         ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
32723         ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
32724         ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
32725         ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, 1, &heap);
32726         ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, gpu_handle);
32727         ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
32728 
32729         transition_resource_state(command_list, context.render_target,
32730                 D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
32731         check_sub_resource_uvec4(context.render_target, 0, queue, command_list, &test->expected_result);
32732         reset_command_list(command_list, context.allocator);
32733 
32734         ID3D12Resource_Release(buffer);
32735     }
32736     vkd3d_test_set_context(NULL);
32737 
32738     ID3D12Resource_Release(vb);
32739     ID3D12DescriptorHeap_Release(heap);
32740     destroy_test_context(&context);
32741 }
32742 
test_write_buffer_immediate(void)32743 static void test_write_buffer_immediate(void)
32744 {
32745     D3D12_WRITEBUFFERIMMEDIATE_PARAMETER parameters[2];
32746     ID3D12GraphicsCommandList2 *command_list2;
32747     D3D12_WRITEBUFFERIMMEDIATE_MODE modes[2];
32748     ID3D12GraphicsCommandList *command_list;
32749     struct resource_readback rb;
32750     struct test_context context;
32751     ID3D12CommandQueue *queue;
32752     ID3D12Resource *buffer;
32753     ID3D12Device *device;
32754     unsigned int value;
32755     HRESULT hr;
32756 
32757     static const unsigned int data_values[] = {0xdeadbeef, 0xf00baa};
32758 
32759     if (!init_test_context(&context, NULL))
32760         return;
32761     device = context.device;
32762     command_list = context.list;
32763     queue = context.queue;
32764 
32765     if (FAILED(hr = ID3D12GraphicsCommandList_QueryInterface(command_list,
32766             &IID_ID3D12GraphicsCommandList2, (void **)&command_list2)))
32767     {
32768         skip("ID3D12GraphicsCommandList2 not implemented.\n");
32769         destroy_test_context(&context);
32770         return;
32771     }
32772 
32773     buffer = create_default_buffer(device, sizeof(data_values),
32774             D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
32775     upload_buffer_data(buffer, 0, sizeof(data_values), data_values, queue, command_list);
32776     reset_command_list(command_list, context.allocator);
32777 
32778     parameters[0].Dest = ID3D12Resource_GetGPUVirtualAddress(buffer);
32779     parameters[0].Value = 0x1020304;
32780     parameters[1].Dest = parameters[0].Dest + sizeof(data_values[0]);
32781     parameters[1].Value = 0xc0d0e0f;
32782     ID3D12GraphicsCommandList2_WriteBufferImmediate(command_list2, ARRAY_SIZE(parameters), parameters, NULL);
32783     hr = ID3D12GraphicsCommandList_Close(command_list);
32784     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
32785     exec_command_list(queue, command_list);
32786     wait_queue_idle(device, queue);
32787     reset_command_list(command_list, context.allocator);
32788 
32789     get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
32790     value = get_readback_uint(&rb, 0, 0, 0);
32791     todo ok(value == parameters[0].Value, "Got unexpected value %#x, expected %#x.\n", value, parameters[0].Value);
32792     value = get_readback_uint(&rb, 1, 0, 0);
32793     todo ok(value == parameters[1].Value, "Got unexpected value %#x, expected %#x.\n", value, parameters[1].Value);
32794     release_resource_readback(&rb);
32795     reset_command_list(command_list, context.allocator);
32796 
32797     parameters[0].Value = 0x2030405;
32798     parameters[1].Value = 0xb0c0d0e;
32799     modes[0] = D3D12_WRITEBUFFERIMMEDIATE_MODE_MARKER_IN;
32800     modes[1] = D3D12_WRITEBUFFERIMMEDIATE_MODE_MARKER_OUT;
32801     ID3D12GraphicsCommandList2_WriteBufferImmediate(command_list2, ARRAY_SIZE(parameters), parameters, modes);
32802     hr = ID3D12GraphicsCommandList_Close(command_list);
32803     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
32804     exec_command_list(queue, command_list);
32805     wait_queue_idle(device, queue);
32806     reset_command_list(command_list, context.allocator);
32807 
32808     get_buffer_readback_with_command_list(buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
32809     value = get_readback_uint(&rb, 0, 0, 0);
32810     todo ok(value == parameters[0].Value, "Got unexpected value %#x, expected %#x.\n", value, parameters[0].Value);
32811     value = get_readback_uint(&rb, 1, 0, 0);
32812     todo ok(value == parameters[1].Value, "Got unexpected value %#x, expected %#x.\n", value, parameters[1].Value);
32813     release_resource_readback(&rb);
32814     reset_command_list(command_list, context.allocator);
32815 
32816     modes[0] = 0x7fffffff;
32817     ID3D12GraphicsCommandList2_WriteBufferImmediate(command_list2, ARRAY_SIZE(parameters), parameters, modes);
32818     hr = ID3D12GraphicsCommandList_Close(command_list);
32819     todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
32820 
32821     ID3D12Resource_Release(buffer);
32822     ID3D12GraphicsCommandList2_Release(command_list2);
32823     destroy_test_context(&context);
32824 }
32825 
test_register_space(void)32826 static void test_register_space(void)
32827 {
32828     ID3D12Resource *input_buffers[6], *output_buffers[8], *counter_buffers[2];
32829     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
32830     D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
32831     D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
32832     ID3D12GraphicsCommandList *command_list;
32833     unsigned int descriptor_count;
32834     struct test_context context;
32835     ID3D12DescriptorHeap *heap;
32836     ID3D12CommandQueue *queue;
32837     ID3D12Device *device;
32838     uint32_t counter;
32839     unsigned int i;
32840     HRESULT hr;
32841 
32842     static const D3D12_DESCRIPTOR_RANGE descriptor_ranges[] =
32843     {
32844         {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 1, 2, 0},
32845         {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 1, 1, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
32846         {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 2, 2, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
32847         {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 3, 1, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
32848 
32849         {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 1, 1, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
32850         {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 2, 1, 2, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
32851         {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 2, 2, 1, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
32852         {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 3, 2, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
32853         {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 3, 4, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
32854         {D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 3, 3, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
32855     };
32856 
32857     static const D3D12_ROOT_PARAMETER root_parameters[] =
32858     {
32859         {D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
32860                     .DescriptorTable = {ARRAY_SIZE(descriptor_ranges), descriptor_ranges}},
32861         {D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, .Constants = {1, 1, 1}},
32862         {D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, .Constants = {1, 2, 1}},
32863     };
32864 
32865     static const DWORD cs_code[] =
32866     {
32867 #if 0
32868         cbuffer cb1 : register(b1, space1)
32869         {
32870             uint c1;
32871         }
32872         cbuffer cb2 : register(b1, space2)
32873         {
32874             uint c2;
32875         }
32876 
32877         ByteAddressBuffer t1 : register(t1, space2);
32878         ByteAddressBuffer t2 : register(t1, space1);
32879 
32880         Buffer<uint> t3 : register(t2, space1);
32881         Buffer<uint> t4 : register(t2, space2);
32882 
32883         StructuredBuffer<uint> t5 : register(t3, space1);
32884         StructuredBuffer<uint> t6 : register(t3, space2);
32885 
32886         RWByteAddressBuffer u1 : register(u1, space1);
32887         RWByteAddressBuffer u2 : register(u1, space2);
32888         RWByteAddressBuffer u3 : register(u2, space1);
32889         RWByteAddressBuffer u4 : register(u2, space2);
32890 
32891         RWBuffer<uint> u5 : register(u3, space1);
32892         RWBuffer<uint> u6 : register(u3, space2);
32893 
32894         RWStructuredBuffer<uint> u7 : register(u3, space4);
32895         RWStructuredBuffer<uint> u8 : register(u3, space3);
32896 
32897         [numthreads(1, 1, 1)]
32898         void main()
32899         {
32900             u1.Store(0, t1.Load(0));
32901             u2.Store(0, t2.Load(0));
32902             u3.Store(0, t3.Load(0));
32903             u4.Store(0, t4.Load(0));
32904             u5[0] = t5.Load(0);
32905             u6[0] = t6.Load(0);
32906             u7[0] = c1;
32907             u8[0] = c2;
32908             u7.IncrementCounter();
32909             u8.DecrementCounter();
32910         }
32911 #endif
32912         0x43425844, 0x2a87323a, 0x4f83d345, 0x707e5d14, 0xdf41ce4a, 0x00000001, 0x00000474, 0x00000003,
32913         0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
32914         0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000420, 0x00050051, 0x00000108, 0x0100086a,
32915         0x07000059, 0x00308e46, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x07000059,
32916         0x00308e46, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x060000a1, 0x00307e46,
32917         0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x07000858, 0x00307e46, 0x00000001, 0x00000002,
32918         0x00000002, 0x00004444, 0x00000001, 0x070000a2, 0x00307e46, 0x00000002, 0x00000003, 0x00000003,
32919         0x00000004, 0x00000001, 0x060000a1, 0x00307e46, 0x00000003, 0x00000001, 0x00000001, 0x00000002,
32920         0x07000858, 0x00307e46, 0x00000004, 0x00000002, 0x00000002, 0x00004444, 0x00000002, 0x070000a2,
32921         0x00307e46, 0x00000005, 0x00000003, 0x00000003, 0x00000004, 0x00000002, 0x0600009d, 0x0031ee46,
32922         0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0600009d, 0x0031ee46, 0x00000001, 0x00000002,
32923         0x00000002, 0x00000001, 0x0700089c, 0x0031ee46, 0x00000002, 0x00000003, 0x00000003, 0x00004444,
32924         0x00000001, 0x0600009d, 0x0031ee46, 0x00000003, 0x00000001, 0x00000001, 0x00000002, 0x0600009d,
32925         0x0031ee46, 0x00000004, 0x00000002, 0x00000002, 0x00000002, 0x0700089c, 0x0031ee46, 0x00000005,
32926         0x00000003, 0x00000003, 0x00004444, 0x00000002, 0x0780009e, 0x0031ee46, 0x00000006, 0x00000003,
32927         0x00000003, 0x00000004, 0x00000003, 0x0780009e, 0x0031ee46, 0x00000007, 0x00000003, 0x00000003,
32928         0x00000004, 0x00000004, 0x02000068, 0x00000001, 0x0400009b, 0x00000001, 0x00000001, 0x00000001,
32929         0x080000a5, 0x00100012, 0x00000000, 0x00004001, 0x00000000, 0x00207006, 0x00000003, 0x00000001,
32930         0x080000a6, 0x0021e012, 0x00000000, 0x00000001, 0x00004001, 0x00000000, 0x0010000a, 0x00000000,
32931         0x080000a5, 0x00100012, 0x00000000, 0x00004001, 0x00000000, 0x00207006, 0x00000000, 0x00000001,
32932         0x080000a6, 0x0021e012, 0x00000003, 0x00000001, 0x00004001, 0x00000000, 0x0010000a, 0x00000000,
32933         0x0b00002d, 0x00100012, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
32934         0x00207e46, 0x00000001, 0x00000002, 0x080000a6, 0x0021e012, 0x00000001, 0x00000002, 0x00004001,
32935         0x00000000, 0x0010000a, 0x00000000, 0x0b00002d, 0x00100012, 0x00000000, 0x00004002, 0x00000000,
32936         0x00000000, 0x00000000, 0x00000000, 0x00207e46, 0x00000004, 0x00000002, 0x080000a6, 0x0021e012,
32937         0x00000004, 0x00000002, 0x00004001, 0x00000000, 0x0010000a, 0x00000000, 0x0a0000a7, 0x00100012,
32938         0x00000000, 0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x00207006, 0x00000002, 0x00000003,
32939         0x0b0000a4, 0x0021e0f2, 0x00000002, 0x00000003, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
32940         0x00000000, 0x00100006, 0x00000000, 0x0a0000a7, 0x00100012, 0x00000000, 0x00004001, 0x00000000,
32941         0x00004001, 0x00000000, 0x00207006, 0x00000005, 0x00000003, 0x0b0000a4, 0x0021e0f2, 0x00000005,
32942         0x00000003, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00100006, 0x00000000,
32943         0x0c0000a8, 0x0021e012, 0x00000007, 0x00000003, 0x00004001, 0x00000000, 0x00004001, 0x00000000,
32944         0x0030800a, 0x00000000, 0x00000001, 0x00000000, 0x0c0000a8, 0x0021e012, 0x00000006, 0x00000003,
32945         0x00004001, 0x00000000, 0x00004001, 0x00000000, 0x0030800a, 0x00000001, 0x00000001, 0x00000000,
32946         0x060000b2, 0x00100012, 0x00000000, 0x0021e000, 0x00000007, 0x00000003, 0x060000b3, 0x00100012,
32947         0x00000000, 0x0021e000, 0x00000006, 0x00000003, 0x0100003e,
32948     };
32949     static const uint32_t uav_data[] = {100, 200, 400, 300, 600, 500, 700, 800};
32950     static const uint32_t srv_data[] = {100, 200, 300, 400, 500, 600};
32951 
32952     if (!init_compute_test_context(&context))
32953         return;
32954     device = context.device;
32955     command_list = context.list;
32956     queue = context.queue;
32957 
32958     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
32959     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
32960     root_signature_desc.pParameters = root_parameters;
32961     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
32962     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
32963 
32964     for (i = 0, descriptor_count = 0; i < ARRAY_SIZE(descriptor_ranges); ++i)
32965     {
32966         descriptor_count += descriptor_ranges[i].NumDescriptors;
32967     }
32968     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, descriptor_count);
32969 
32970     for (i = 0; i < ARRAY_SIZE(input_buffers); ++i)
32971     {
32972         input_buffers[i] = create_default_buffer(device, sizeof(uint32_t),
32973                 D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COPY_DEST);
32974         upload_buffer_data(input_buffers[i], 0, sizeof(srv_data[i]), &srv_data[i], queue, command_list);
32975         reset_command_list(command_list, context.allocator);
32976         transition_resource_state(command_list, input_buffers[i],
32977                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
32978 
32979         memset(&srv_desc, 0, sizeof(srv_desc));
32980         srv_desc.Format = DXGI_FORMAT_R32_UINT;
32981         srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
32982         srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
32983         srv_desc.Buffer.FirstElement = 0;
32984         srv_desc.Buffer.NumElements = 1;
32985         ID3D12Device_CreateShaderResourceView(device, input_buffers[i], &srv_desc,
32986                 get_cpu_descriptor_handle(&context, heap, i));
32987     }
32988 
32989     for (i = 0; i < ARRAY_SIZE(counter_buffers); ++i)
32990     {
32991         counter_buffers[i] = create_default_buffer(device, sizeof(uint32_t),
32992                 D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST);
32993         counter = 2;
32994         upload_buffer_data(counter_buffers[i], 0, sizeof(counter), &counter, queue, command_list);
32995         reset_command_list(command_list, context.allocator);
32996         transition_sub_resource_state(command_list, counter_buffers[i], 0,
32997                 D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
32998     }
32999 
33000     for (i = 0; i < ARRAY_SIZE(output_buffers); ++i)
33001     {
33002         output_buffers[i] = create_default_buffer(device, sizeof(uint32_t),
33003                 D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
33004 
33005         memset(&uav_desc, 0, sizeof(uav_desc));
33006         uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
33007         uav_desc.Buffer.FirstElement = 0;
33008         uav_desc.Buffer.NumElements = 1;
33009         if (i < 6)
33010         {
33011             uav_desc.Format = DXGI_FORMAT_R32_UINT;
33012         }
33013         else
33014         {
33015             uav_desc.Format = DXGI_FORMAT_UNKNOWN;
33016             uav_desc.Buffer.StructureByteStride = sizeof(uint32_t);
33017         }
33018         ID3D12Device_CreateUnorderedAccessView(device, output_buffers[i], i >= 6 ? counter_buffers[i - 6] : NULL,
33019                 &uav_desc, get_cpu_descriptor_handle(&context, heap, ARRAY_SIZE(input_buffers) + i));
33020     }
33021 
33022     context.pipeline_state = create_compute_pipeline_state(device, context.root_signature,
33023             shader_bytecode(cs_code, sizeof(cs_code)));
33024 
33025     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
33026     ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
33027     ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list,
33028             0, get_gpu_descriptor_handle(&context, heap, 0));
33029     ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(command_list, 1, 700, 0);
33030     ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(command_list, 2, 800, 0);
33031 
33032     ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
33033 
33034     for (i = 0; i < ARRAY_SIZE(output_buffers); ++i)
33035     {
33036         transition_sub_resource_state(command_list, output_buffers[i], 0,
33037                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
33038         check_buffer_uint(output_buffers[i], queue, command_list, uav_data[i], 0);
33039         reset_command_list(command_list, context.allocator);
33040     }
33041 
33042     counter = read_uav_counter(&context, counter_buffers[0], 0);
33043     ok(counter == 3, "Got unexpected value %d.\n", counter);
33044     counter = read_uav_counter(&context, counter_buffers[1], 0);
33045     ok(counter == 1, "Got unexpected value %d.\n", counter);
33046 
33047     for (i = 0; i < ARRAY_SIZE(input_buffers); ++i)
33048         ID3D12Resource_Release(input_buffers[i]);
33049     for (i = 0; i < ARRAY_SIZE(output_buffers); ++i)
33050         ID3D12Resource_Release(output_buffers[i]);
33051     for (i = 0; i < ARRAY_SIZE(counter_buffers); ++i)
33052         ID3D12Resource_Release(counter_buffers[i]);
33053     ID3D12DescriptorHeap_Release(heap);
33054     destroy_test_context(&context);
33055 }
33056 
test_sampler_register_space(void)33057 static void test_sampler_register_space(void)
33058 {
33059     static const struct test_context_desc desc = {.no_root_signature = true};
33060     ID3D12DescriptorHeap *heap, *sampler_heap, *heaps[2];
33061     D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
33062     ID3D12GraphicsCommandList *command_list;
33063     D3D12_SAMPLER_DESC sampler_desc;
33064     D3D12_SUBRESOURCE_DATA data;
33065     struct test_context context;
33066     ID3D12CommandQueue *queue;
33067     ID3D12Resource *texture;
33068     ID3D12Device *device;
33069     HRESULT hr;
33070 
33071     static const D3D12_DESCRIPTOR_RANGE descriptor_ranges[] =
33072     {
33073         {D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 0, 0},
33074     };
33075 
33076     static const D3D12_DESCRIPTOR_RANGE sampler_ranges[] =
33077     {
33078         {D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 1, 1, 0},
33079         {D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 1, 2, D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND},
33080     };
33081 
33082     static const D3D12_ROOT_PARAMETER root_parameters[] =
33083     {
33084         {D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
33085                     .DescriptorTable = {ARRAY_SIZE(descriptor_ranges), descriptor_ranges}},
33086         {D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
33087                     .DescriptorTable = {ARRAY_SIZE(sampler_ranges), sampler_ranges}},
33088     };
33089 
33090     static const DWORD ps_code[] =
33091     {
33092 #if 0
33093         Texture2D<float> t;
33094         SamplerState s1 : register(s1, space1);
33095         SamplerState s2 : register(s1, space2);
33096 
33097         float4 main() : SV_Target
33098         {
33099             float2 coords = float2(0.5, 0.5);
33100             return float4(t.Sample(s1, coords), t.Sample(s2, coords), 0, 1);
33101         }
33102 #endif
33103         0x43425844, 0xa29c83c7, 0xd4c8eeff, 0x7b73ff7b, 0x6463d58c, 0x00000001, 0x0000018c, 0x00000003,
33104         0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
33105         0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
33106         0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000114, 0x00000051, 0x00000045,
33107         0x0100086a, 0x0600005a, 0x00306e46, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x0600005a,
33108         0x00306e46, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x07001858, 0x00307e46, 0x00000000,
33109         0x00000000, 0x00000000, 0x00005555, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
33110         0x00000001, 0x0e000045, 0x00100012, 0x00000000, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000,
33111         0x00000000, 0x00207e46, 0x00000000, 0x00000000, 0x00206000, 0x00000000, 0x00000001, 0x0e000045,
33112         0x00100022, 0x00000000, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00207e16,
33113         0x00000000, 0x00000000, 0x00206000, 0x00000001, 0x00000001, 0x05000036, 0x00102032, 0x00000000,
33114         0x00100046, 0x00000000, 0x08000036, 0x001020c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000,
33115         0x00000000, 0x00000000, 0x0100003e,
33116     };
33117     static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
33118     static const float texture_data[4] = {0.0, 1.0, 0.0, 1.0};
33119     static const float blue[] = {0.0f, 0.0f, 1.0f, 1.0f};
33120 
33121     if (!init_test_context(&context, &desc))
33122         return;
33123     device = context.device;
33124     command_list = context.list;
33125     queue = context.queue;
33126 
33127     memset(&root_signature_desc, 0, sizeof(root_signature_desc));
33128     root_signature_desc.NumParameters = ARRAY_SIZE(root_parameters);
33129     root_signature_desc.pParameters = root_parameters;
33130     hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
33131     ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
33132 
33133     heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, ARRAY_SIZE(descriptor_ranges));
33134     sampler_heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, ARRAY_SIZE(sampler_ranges));
33135 
33136     texture = create_default_texture(device, 2, 2, DXGI_FORMAT_R32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
33137     data.pData = texture_data;
33138     data.SlicePitch = data.RowPitch = 2 * sizeof(*texture_data);
33139     upload_texture_data(texture, &data, 1, queue, command_list);
33140     reset_command_list(command_list, context.allocator);
33141     transition_resource_state(command_list, texture,
33142             D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
33143     ID3D12Device_CreateShaderResourceView(device, texture, NULL, get_cpu_descriptor_handle(&context, heap, 0));
33144 
33145     memset(&sampler_desc, 0, sizeof(sampler_desc));
33146     sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
33147     sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
33148     sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
33149     sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
33150     ID3D12Device_CreateSampler(device, &sampler_desc, get_cpu_sampler_handle(&context, sampler_heap, 0));
33151     sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
33152     ID3D12Device_CreateSampler(device, &sampler_desc, get_cpu_sampler_handle(&context, sampler_heap, 1));
33153 
33154     context.pipeline_state = create_pipeline_state(device, context.root_signature,
33155             context.render_target_desc.Format, NULL, &ps, NULL);
33156 
33157     ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, blue, 0, NULL);
33158     ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL);
33159     ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
33160     ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
33161     heaps[0] = heap; heaps[1] = sampler_heap;
33162     ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, ARRAY_SIZE(heaps), heaps);
33163     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list,
33164             0, get_gpu_descriptor_handle(&context, heap, 0));
33165     ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list,
33166             1, get_gpu_sampler_handle(&context, sampler_heap, 0));
33167     ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
33168     ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
33169     ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
33170     ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
33171 
33172     transition_resource_state(command_list, context.render_target,
33173             D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
33174     check_sub_resource_uint(context.render_target, 0, queue, command_list, 0x0000ff80, 1);
33175 
33176     ID3D12Resource_Release(texture);
33177     ID3D12DescriptorHeap_Release(heap);
33178     ID3D12DescriptorHeap_Release(sampler_heap);
33179     destroy_test_context(&context);
33180 }
33181 
START_TEST(d3d12)33182 START_TEST(d3d12)
33183 {
33184     parse_args(argc, argv);
33185     enable_d3d12_debug_layer(argc, argv);
33186     init_adapter_info();
33187 
33188     pfn_D3D12CreateVersionedRootSignatureDeserializer = get_d3d12_pfn(D3D12CreateVersionedRootSignatureDeserializer);
33189     pfn_D3D12SerializeVersionedRootSignature = get_d3d12_pfn(D3D12SerializeVersionedRootSignature);
33190 
33191     run_test(test_create_device);
33192     run_test(test_node_count);
33193     run_test(test_check_feature_support);
33194     run_test(test_format_support);
33195     run_test(test_multisample_quality_levels);
33196     run_test(test_create_command_allocator);
33197     run_test(test_create_command_list);
33198     run_test(test_create_command_queue);
33199     run_test(test_create_command_signature);
33200     run_test(test_create_committed_resource);
33201     run_test(test_create_heap);
33202     run_test(test_create_placed_resource);
33203     run_test(test_create_reserved_resource);
33204     run_test(test_create_descriptor_heap);
33205     run_test(test_create_sampler);
33206     run_test(test_create_unordered_access_view);
33207     run_test(test_create_root_signature);
33208     run_test(test_root_signature_limits);
33209     run_test(test_create_compute_pipeline_state);
33210     run_test(test_create_graphics_pipeline_state);
33211     run_test(test_create_fence);
33212     run_test(test_object_interface);
33213     run_test(test_multithread_private_data);
33214     run_test(test_reset_command_allocator);
33215     run_test(test_cpu_signal_fence);
33216     run_test(test_gpu_signal_fence);
33217     run_test(test_multithread_fence_wait);
33218     run_test(test_fence_values);
33219     run_test(test_clear_depth_stencil_view);
33220     run_test(test_clear_render_target_view);
33221     run_test(test_clear_unordered_access_view_buffer);
33222     run_test(test_clear_unordered_access_view_image);
33223     run_test(test_set_render_targets);
33224     run_test(test_draw_instanced);
33225     run_test(test_draw_indexed_instanced);
33226     run_test(test_draw_no_descriptor_bindings);
33227     run_test(test_multiple_render_targets);
33228     run_test(test_unknown_rtv_format);
33229     run_test(test_unknown_dsv_format);
33230     run_test(test_append_aligned_element);
33231     run_test(test_gpu_virtual_address);
33232     run_test(test_fragment_coords);
33233     run_test(test_fractional_viewports);
33234     run_test(test_scissor);
33235     run_test(test_draw_depth_no_ps);
33236     run_test(test_draw_depth_only);
33237     run_test(test_draw_uav_only);
33238     run_test(test_texture_resource_barriers);
33239     run_test(test_device_removed_reason);
33240     run_test(test_map_resource);
33241     run_test(test_map_placed_resources);
33242     run_test(test_bundle_state_inheritance);
33243     run_test(test_shader_instructions);
33244     run_test(test_compute_shader_instructions);
33245     run_test(test_discard_instruction);
33246     run_test(test_shader_interstage_interface);
33247     run_test(test_shader_input_output_components);
33248     run_test(test_root_signature_byte_code);
33249     run_test(test_cs_constant_buffer);
33250     run_test(test_constant_buffer_relative_addressing);
33251     run_test(test_immediate_constant_buffer);
33252     run_test(test_root_constants);
33253     run_test(test_sample_instructions);
33254     run_test(test_texture_ld);
33255     run_test(test_gather);
33256     run_test(test_gather_c);
33257     run_test(test_sample_c_lz);
33258     run_test(test_cube_maps);
33259     run_test(test_multisample_array_texture);
33260     run_test(test_resinfo);
33261     run_test(test_srv_component_mapping);
33262     run_test(test_descriptor_tables);
33263     run_test(test_descriptor_tables_overlapping_bindings);
33264     run_test(test_update_root_descriptors);
33265     run_test(test_update_descriptor_tables);
33266     run_test(test_update_descriptor_heap_after_closing_command_list);
33267     run_test(test_update_compute_descriptor_tables);
33268     run_test(test_update_descriptor_tables_after_root_signature_change);
33269     run_test(test_copy_descriptors);
33270     run_test(test_copy_descriptors_range_sizes);
33271     run_test(test_descriptors_visibility);
33272     run_test(test_create_null_descriptors);
33273     run_test(test_null_cbv);
33274     run_test(test_null_srv);
33275     run_test(test_null_uav);
33276     run_test(test_null_vbv);
33277     run_test(test_get_copyable_footprints);
33278     run_test(test_depth_clip);
33279     run_test(test_depth_stencil_sampling);
33280     run_test(test_depth_load);
33281     run_test(test_depth_read_only_view);
33282     run_test(test_stencil_load);
33283     run_test(test_typed_buffer_uav);
33284     run_test(test_typed_uav_store);
33285     run_test(test_compute_shader_registers);
33286     run_test(test_tgsm);
33287     run_test(test_uav_load);
33288     run_test(test_cs_uav_store);
33289     run_test(test_uav_counters);
33290     run_test(test_decrement_uav_counter);
33291     run_test(test_atomic_instructions);
33292     run_test(test_buffer_srv);
33293     run_test(test_create_query_heap);
33294     run_test(test_query_timestamp);
33295     run_test(test_query_pipeline_statistics);
33296     run_test(test_query_occlusion);
33297     run_test(test_resolve_non_issued_query_data);
33298     run_test(test_resolve_query_data_in_different_command_list);
33299     run_test(test_resolve_query_data_in_reordered_command_list);
33300     run_test(test_execute_indirect);
33301     run_test(test_dispatch_zero_thread_groups);
33302     run_test(test_zero_vertex_stride);
33303     run_test(test_instance_id);
33304     run_test(test_vertex_id);
33305     run_test(test_copy_texture);
33306     run_test(test_copy_texture_buffer);
33307     run_test(test_copy_buffer_texture);
33308     run_test(test_copy_block_compressed_texture);
33309     run_test(test_separate_bindings);
33310     run_test(test_face_culling);
33311     run_test(test_multithread_command_queue_exec);
33312     run_test(test_geometry_shader);
33313     run_test(test_layered_rendering);
33314     run_test(test_ps_layer);
33315     run_test(test_nop_tessellation_shaders);
33316     run_test(test_quad_tessellation);
33317     run_test(test_tessellation_dcl_index_range);
33318     run_test(test_hull_shader_control_point_phase);
33319     run_test(test_hull_shader_fork_phase);
33320     run_test(test_line_tessellation);
33321     run_test(test_tessellation_primitive_id);
33322     run_test(test_render_a8);
33323     run_test(test_cpu_descriptors_lifetime);
33324     run_test(test_clip_distance);
33325     run_test(test_combined_clip_and_cull_distances);
33326     run_test(test_resource_allocation_info);
33327     run_test(test_suballocate_small_textures);
33328     run_test(test_command_list_initial_pipeline_state);
33329     run_test(test_blend_factor);
33330     run_test(test_dual_source_blending);
33331     run_test(test_multisample_rendering);
33332     run_test(test_sample_mask);
33333     run_test(test_coverage);
33334     run_test(test_shader_get_render_target_sample_count);
33335     run_test(test_shader_sample_position);
33336     run_test(test_shader_eval_attribute);
33337     run_test(test_primitive_restart);
33338     run_test(test_vertex_shader_stream_output);
33339     run_test(test_read_write_subresource);
33340     run_test(test_queue_wait);
33341     run_test(test_graphics_compute_queue_synchronization);
33342     run_test(test_early_depth_stencil_tests);
33343     run_test(test_conditional_rendering);
33344     run_test(test_bufinfo_instruction);
33345     run_test(test_write_buffer_immediate);
33346     run_test(test_register_space);
33347     run_test(test_sampler_register_space);
33348 }
33349