2 * Copyright 2020-2021 Zebediah Figura for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define WIDL_C_INLINE_WRAPPERS
26 #define VKD3D_TEST_NO_DEFS
27 #include "d3d12_crosstest.h"
28 #include "shader_runner.h"
29 #include "dxcompiler.h"
31 VKD3D_AGILITY_SDK_EXPORTS
37 D3D12_DESCRIPTOR_RANGE descriptor_range
;
38 ID3D12Resource
*resource
;
39 unsigned int root_index
;
42 static struct d3d12_resource
*d3d12_resource(struct resource
*r
)
44 return CONTAINING_RECORD(r
, struct d3d12_resource
, r
);
47 struct d3d12_shader_runner
49 struct shader_runner r
;
50 struct shader_runner_caps caps
;
52 struct test_context test_context
;
54 ID3D12DescriptorHeap
*heap
, *rtv_heap
, *dsv_heap
;
56 ID3D12CommandQueue
*compute_queue
;
57 ID3D12CommandAllocator
*compute_allocator
;
58 ID3D12GraphicsCommandList
*compute_list
;
61 static struct d3d12_shader_runner
*d3d12_shader_runner(struct shader_runner
*r
)
63 return CONTAINING_RECORD(r
, struct d3d12_shader_runner
, r
);
66 #define MAX_RESOURCE_DESCRIPTORS (MAX_RESOURCES * 2)
68 static D3D12_RESOURCE_STATES
resource_get_state(struct resource
*r
)
70 if (r
->desc
.type
== RESOURCE_TYPE_RENDER_TARGET
)
71 return D3D12_RESOURCE_STATE_RENDER_TARGET
;
72 if (r
->desc
.type
== RESOURCE_TYPE_DEPTH_STENCIL
)
73 return D3D12_RESOURCE_STATE_DEPTH_WRITE
;
74 if (r
->desc
.type
== RESOURCE_TYPE_TEXTURE
)
75 return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE
| D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
;
76 if (r
->desc
.type
== RESOURCE_TYPE_UAV
)
77 return D3D12_RESOURCE_STATE_UNORDERED_ACCESS
;
78 return D3D12_RESOURCE_STATE_GENERIC_READ
;
81 static struct resource
*d3d12_runner_create_resource(struct shader_runner
*r
, const struct resource_params
*params
)
83 struct d3d12_shader_runner
*runner
= d3d12_shader_runner(r
);
84 struct test_context
*test_context
= &runner
->test_context
;
85 ID3D12Device
*device
= test_context
->device
;
86 D3D12_SUBRESOURCE_DATA resource_data
[3] = {0};
87 D3D12_RESOURCE_STATES initial_state
, state
;
88 struct d3d12_resource
*resource
;
89 unsigned int buffer_offset
= 0;
91 if (params
->desc
.level_count
> ARRAY_SIZE(resource_data
))
92 fatal_error("Level count %u is too high.\n", params
->desc
.level_count
);
94 resource
= calloc(1, sizeof(*resource
));
95 init_resource(&resource
->r
, params
);
97 for (unsigned int level
= 0; level
< params
->desc
.level_count
; ++level
)
99 unsigned int level_width
= get_level_dimension(params
->desc
.width
, level
);
100 unsigned int level_height
= get_level_dimension(params
->desc
.height
, level
);
102 resource_data
[level
].pData
= ¶ms
->data
[buffer_offset
];
103 resource_data
[level
].RowPitch
= level_width
* params
->desc
.texel_size
;
104 resource_data
[level
].SlicePitch
= level_height
* resource_data
[level
].RowPitch
;
105 buffer_offset
+= resource_data
[level
].SlicePitch
;
108 state
= resource_get_state(&resource
->r
);
109 initial_state
= params
->data
? D3D12_RESOURCE_STATE_COPY_DEST
: state
;
111 switch (params
->desc
.type
)
113 case RESOURCE_TYPE_RENDER_TARGET
:
114 if (!runner
->rtv_heap
)
115 runner
->rtv_heap
= create_cpu_descriptor_heap(device
,
116 D3D12_DESCRIPTOR_HEAP_TYPE_RTV
, MAX_RESOURCE_DESCRIPTORS
);
118 if (params
->desc
.slot
>= D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT
)
119 fatal_error("RTV slot %u is too high.\n", params
->desc
.slot
);
120 if (params
->desc
.sample_count
> 1 && params
->desc
.level_count
> 1)
121 fatal_error("Multisampled texture has multiple levels.\n");
123 resource
->resource
= create_default_texture_(__FILE__
, __LINE__
, device
,
124 D3D12_RESOURCE_DIMENSION_TEXTURE2D
, params
->desc
.width
, params
->desc
.height
,
125 params
->desc
.depth
, params
->desc
.level_count
, params
->desc
.sample_count
,
126 params
->desc
.format
, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET
, initial_state
);
127 ID3D12Device_CreateRenderTargetView(device
, resource
->resource
,
128 NULL
, get_cpu_rtv_handle(test_context
, runner
->rtv_heap
, resource
->r
.desc
.slot
));
131 case RESOURCE_TYPE_DEPTH_STENCIL
:
132 if (!runner
->dsv_heap
)
133 runner
->dsv_heap
= create_cpu_descriptor_heap(device
, D3D12_DESCRIPTOR_HEAP_TYPE_DSV
, 1);
135 resource
->resource
= create_default_texture2d(device
, params
->desc
.width
,
136 params
->desc
.height
, params
->desc
.depth
, params
->desc
.level_count
,
137 params
->desc
.format
, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL
, initial_state
);
138 ID3D12Device_CreateDepthStencilView(device
, resource
->resource
,
139 NULL
, get_cpu_dsv_handle(test_context
, runner
->dsv_heap
, 0));
142 case RESOURCE_TYPE_TEXTURE
:
144 runner
->heap
= create_gpu_descriptor_heap(device
,
145 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV
, MAX_RESOURCE_DESCRIPTORS
);
147 if (params
->desc
.dimension
== RESOURCE_DIMENSION_BUFFER
)
149 D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc
= { 0 };
151 resource
->resource
= create_default_buffer(device
, params
->data_size
, 0, initial_state
);
154 upload_buffer_data_with_states(resource
->resource
, 0, params
->data_size
, resource_data
[0].pData
,
155 test_context
->queue
, test_context
->list
, RESOURCE_STATE_DO_NOT_CHANGE
, state
);
156 reset_command_list(test_context
->list
, test_context
->allocator
);
159 srv_desc
.Format
= params
->desc
.format
;
160 srv_desc
.ViewDimension
= D3D12_SRV_DIMENSION_BUFFER
;
161 srv_desc
.Shader4ComponentMapping
= D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING
;
162 srv_desc
.Buffer
.NumElements
= params
->desc
.width
* params
->desc
.height
;
163 srv_desc
.Buffer
.Flags
= params
->is_raw
? D3D12_BUFFER_SRV_FLAG_RAW
: 0;
165 ID3D12Device_CreateShaderResourceView(device
, resource
->resource
,
166 &srv_desc
, get_cpu_descriptor_handle(test_context
, runner
->heap
, resource
->r
.desc
.slot
));
170 if (params
->desc
.sample_count
> 1 && params
->desc
.level_count
> 1)
171 fatal_error("Multisampled texture has multiple levels.\n");
173 resource
->resource
= create_default_texture_(__FILE__
, __LINE__
, device
,
174 D3D12_RESOURCE_DIMENSION_TEXTURE2D
, params
->desc
.width
, params
->desc
.height
,
175 params
->desc
.depth
, params
->desc
.level_count
, params
->desc
.sample_count
, params
->desc
.format
,
176 /* Multisampled textures must have ALLOW_RENDER_TARGET set. */
177 (params
->desc
.sample_count
> 1) ? D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET
: 0, initial_state
);
180 if (params
->desc
.sample_count
> 1)
181 fatal_error("Cannot upload data to a multisampled texture.\n");
182 upload_texture_data_with_states(resource
->resource
, resource_data
, params
->desc
.level_count
,
183 test_context
->queue
, test_context
->list
, RESOURCE_STATE_DO_NOT_CHANGE
, state
);
184 reset_command_list(test_context
->list
, test_context
->allocator
);
187 ID3D12Device_CreateShaderResourceView(device
, resource
->resource
,
188 NULL
, get_cpu_descriptor_handle(test_context
, runner
->heap
, resource
->r
.desc
.slot
));
192 case RESOURCE_TYPE_UAV
:
194 runner
->heap
= create_gpu_descriptor_heap(device
,
195 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV
, MAX_RESOURCE_DESCRIPTORS
);
197 if (params
->desc
.dimension
== RESOURCE_DIMENSION_BUFFER
)
199 D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc
= { 0 };
201 resource
->resource
= create_default_buffer(device
, params
->data_size
,
202 D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS
, initial_state
);
205 upload_buffer_data_with_states(resource
->resource
, 0, params
->data_size
, resource_data
[0].pData
,
206 test_context
->queue
, test_context
->list
, RESOURCE_STATE_DO_NOT_CHANGE
, state
);
207 reset_command_list(test_context
->list
, test_context
->allocator
);
210 uav_desc
.Format
= params
->desc
.format
;
211 uav_desc
.ViewDimension
= D3D12_UAV_DIMENSION_BUFFER
;
212 uav_desc
.Buffer
.NumElements
= params
->desc
.width
* params
->desc
.height
;
213 uav_desc
.Buffer
.StructureByteStride
= params
->stride
;
214 uav_desc
.Buffer
.Flags
= params
->is_raw
? D3D12_BUFFER_UAV_FLAG_RAW
: 0;
216 ID3D12Device_CreateUnorderedAccessView(device
, resource
->resource
,
217 params
->is_uav_counter
? resource
->resource
: NULL
, &uav_desc
,
218 get_cpu_descriptor_handle(test_context
, runner
->heap
, resource
->r
.desc
.slot
+ MAX_RESOURCES
));
222 resource
->resource
= create_default_texture2d(device
, params
->desc
.width
,
223 params
->desc
.height
, params
->desc
.depth
, params
->desc
.level_count
,
224 params
->desc
.format
, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS
, initial_state
);
227 upload_texture_data_with_states(resource
->resource
, resource_data
, params
->desc
.level_count
,
228 test_context
->queue
, test_context
->list
, RESOURCE_STATE_DO_NOT_CHANGE
, state
);
229 reset_command_list(test_context
->list
, test_context
->allocator
);
231 ID3D12Device_CreateUnorderedAccessView(device
, resource
->resource
, NULL
, NULL
,
232 get_cpu_descriptor_handle(test_context
, runner
->heap
, resource
->r
.desc
.slot
+ MAX_RESOURCES
));
236 case RESOURCE_TYPE_VERTEX_BUFFER
:
237 resource
->resource
= create_upload_buffer(device
, params
->data_size
, params
->data
);
244 static void d3d12_runner_destroy_resource(struct shader_runner
*r
, struct resource
*res
)
246 struct d3d12_resource
*resource
= d3d12_resource(res
);
248 ID3D12Resource_Release(resource
->resource
);
252 static ID3D12RootSignature
*d3d12_runner_create_root_signature(struct d3d12_shader_runner
*runner
,
253 ID3D12CommandQueue
*queue
, ID3D12CommandAllocator
*allocator
,
254 ID3D12GraphicsCommandList
*command_list
, unsigned int *uniform_index
)
256 D3D12_ROOT_SIGNATURE_DESC root_signature_desc
= {0};
257 D3D12_ROOT_PARAMETER root_params
[17], *root_param
;
258 D3D12_STATIC_SAMPLER_DESC static_samplers
[7];
259 struct d3d12_resource
*base_resource
= NULL
;
260 ID3D12RootSignature
*root_signature
;
265 root_signature_desc
.NumParameters
= 0;
266 root_signature_desc
.pParameters
= root_params
;
267 root_signature_desc
.NumStaticSamplers
= 0;
268 root_signature_desc
.pStaticSamplers
= static_samplers
;
269 root_signature_desc
.Flags
= D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT
;
271 if (runner
->r
.uniform_count
)
273 *uniform_index
= root_signature_desc
.NumParameters
++;
274 root_param
= &root_params
[*uniform_index
];
275 root_param
->ParameterType
= D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS
;
276 root_param
->Constants
.ShaderRegister
= 0;
277 root_param
->Constants
.RegisterSpace
= 0;
278 root_param
->Constants
.Num32BitValues
= runner
->r
.uniform_count
;
279 root_param
->ShaderVisibility
= D3D12_SHADER_VISIBILITY_ALL
;
282 for (i
= 0; i
< runner
->r
.resource_count
; ++i
)
284 struct d3d12_resource
*resource
= d3d12_resource(runner
->r
.resources
[i
]);
285 D3D12_DESCRIPTOR_RANGE
*range
;
287 switch (resource
->r
.desc
.type
)
289 case RESOURCE_TYPE_TEXTURE
:
290 case RESOURCE_TYPE_UAV
:
291 range
= &resource
->descriptor_range
;
293 if (base_resource
&& resource
->r
.desc
.type
== base_resource
->r
.desc
.type
&& resource
->r
.desc
.slot
== slot
+ 1)
295 ++base_resource
->descriptor_range
.NumDescriptors
;
296 resource
->descriptor_range
.NumDescriptors
= 0;
301 resource
->root_index
= root_signature_desc
.NumParameters
++;
302 root_param
= &root_params
[resource
->root_index
];
303 root_param
->ParameterType
= D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE
;
304 root_param
->DescriptorTable
.NumDescriptorRanges
= 1;
305 root_param
->DescriptorTable
.pDescriptorRanges
= range
;
306 root_param
->ShaderVisibility
= D3D12_SHADER_VISIBILITY_ALL
;
308 if (resource
->r
.desc
.type
== RESOURCE_TYPE_UAV
)
309 range
->RangeType
= D3D12_DESCRIPTOR_RANGE_TYPE_UAV
;
311 range
->RangeType
= D3D12_DESCRIPTOR_RANGE_TYPE_SRV
;
312 range
->NumDescriptors
= 1;
313 range
->BaseShaderRegister
= resource
->r
.desc
.slot
;
314 range
->RegisterSpace
= 0;
315 range
->OffsetInDescriptorsFromTableStart
= 0;
317 base_resource
= resource
;
318 slot
= resource
->r
.desc
.slot
;
321 case RESOURCE_TYPE_RENDER_TARGET
:
322 case RESOURCE_TYPE_DEPTH_STENCIL
:
323 case RESOURCE_TYPE_VERTEX_BUFFER
:
328 assert(root_signature_desc
.NumParameters
<= ARRAY_SIZE(root_params
));
330 for (i
= 0; i
< runner
->r
.sampler_count
; ++i
)
332 D3D12_STATIC_SAMPLER_DESC
*sampler_desc
= &static_samplers
[root_signature_desc
.NumStaticSamplers
++];
333 const struct sampler
*sampler
= &runner
->r
.samplers
[i
];
335 memset(sampler_desc
, 0, sizeof(*sampler_desc
));
336 sampler_desc
->Filter
= sampler
->filter
;
337 sampler_desc
->AddressU
= sampler
->u_address
;
338 sampler_desc
->AddressV
= sampler
->v_address
;
339 sampler_desc
->AddressW
= sampler
->w_address
;
340 sampler_desc
->ComparisonFunc
= sampler
->func
;
341 sampler_desc
->MaxLOD
= FLT_MAX
;
342 sampler_desc
->ShaderRegister
= sampler
->slot
;
343 sampler_desc
->RegisterSpace
= 0;
344 sampler_desc
->ShaderVisibility
= D3D12_SHADER_VISIBILITY_ALL
;
347 hr
= create_root_signature(runner
->test_context
.device
, &root_signature_desc
, &root_signature
);
348 ok(hr
== S_OK
, "Failed to create root signature, hr %#x.\n", hr
);
349 return root_signature
;
352 static void add_pso(struct test_context
*test_context
, ID3D12PipelineState
*pso
)
354 vkd3d_array_reserve((void **)&test_context
->pso
, &test_context
->pso_capacity
,
355 test_context
->pso_count
+ 1, sizeof(*test_context
->pso
));
356 test_context
->pso
[test_context
->pso_count
++] = pso
;
359 static bool d3d12_runner_dispatch(struct shader_runner
*r
, unsigned int x
, unsigned int y
, unsigned int z
)
361 struct d3d12_shader_runner
*runner
= d3d12_shader_runner(r
);
362 struct test_context
*test_context
= &runner
->test_context
;
364 ID3D12GraphicsCommandList
*command_list
= runner
->compute_list
;
365 ID3D12CommandAllocator
*allocator
= runner
->compute_allocator
;
366 ID3D12CommandQueue
*queue
= runner
->compute_queue
;
367 ID3D12Device
*device
= test_context
->device
;
368 ID3D12RootSignature
*root_signature
;
369 unsigned int uniform_index
;
370 ID3D12PipelineState
*pso
;
371 D3D12_SHADER_BYTECODE cs
;
376 cs_code
= compile_hlsl(&runner
->r
, SHADER_TYPE_CS
);
377 todo_if(runner
->r
.is_todo
&& runner
->r
.minimum_shader_model
< SHADER_MODEL_6_0
) ok(cs_code
, "Failed to compile shader.\n");
381 root_signature
= d3d12_runner_create_root_signature(runner
, queue
, allocator
, command_list
, &uniform_index
);
383 cs
.pShaderBytecode
= ID3D10Blob_GetBufferPointer(cs_code
);
384 cs
.BytecodeLength
= ID3D10Blob_GetBufferSize(cs_code
);
385 todo_if(runner
->r
.is_todo
)
386 pso
= create_compute_pipeline_state(device
, root_signature
, cs
);
387 ID3D10Blob_Release(cs_code
);
391 ID3D12RootSignature_Release(root_signature
);
395 add_pso(test_context
, pso
);
397 ID3D12GraphicsCommandList_SetComputeRootSignature(command_list
, root_signature
);
398 if (runner
->r
.uniform_count
)
399 ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(command_list
, uniform_index
,
400 runner
->r
.uniform_count
, runner
->r
.uniforms
, 0);
401 for (i
= 0; i
< runner
->r
.resource_count
; ++i
)
403 struct d3d12_resource
*resource
= d3d12_resource(runner
->r
.resources
[i
]);
405 switch (resource
->r
.desc
.type
)
407 case RESOURCE_TYPE_TEXTURE
:
408 if (resource
->descriptor_range
.NumDescriptors
)
409 ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list
, resource
->root_index
,
410 get_gpu_descriptor_handle(test_context
, runner
->heap
, resource
->r
.desc
.slot
));
413 case RESOURCE_TYPE_UAV
:
414 if (resource
->descriptor_range
.NumDescriptors
)
415 ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(command_list
, resource
->root_index
,
416 get_gpu_descriptor_handle(test_context
, runner
->heap
, resource
->r
.desc
.slot
+ MAX_RESOURCES
));
419 case RESOURCE_TYPE_RENDER_TARGET
:
420 case RESOURCE_TYPE_DEPTH_STENCIL
:
421 case RESOURCE_TYPE_VERTEX_BUFFER
:
426 ID3D12GraphicsCommandList_SetPipelineState(command_list
, pso
);
427 ID3D12GraphicsCommandList_Dispatch(command_list
, x
, y
, z
);
428 ID3D12RootSignature_Release(root_signature
);
430 /* Finish the command list so that we can destroy objects.
431 * Also, subsequent UAV probes will use the graphics command list, so make
432 * sure that the above barriers are actually executed. */
433 hr
= ID3D12GraphicsCommandList_Close(command_list
);
434 ok(hr
== S_OK
, "Failed to close command list, hr %#x.\n", hr
);
435 exec_command_list(queue
, command_list
);
436 wait_queue_idle(device
, queue
);
437 reset_command_list(command_list
, allocator
);
442 static void d3d12_runner_clear(struct shader_runner
*r
, struct resource
*resource
, const struct vec4
*clear_value
)
444 struct d3d12_shader_runner
*runner
= d3d12_shader_runner(r
);
445 struct test_context
*test_context
= &runner
->test_context
;
447 ID3D12GraphicsCommandList
*command_list
= test_context
->list
;
448 ID3D12CommandQueue
*queue
= test_context
->queue
;
449 ID3D12Device
*device
= test_context
->device
;
450 D3D12_CPU_DESCRIPTOR_HANDLE view
;
453 switch (resource
->desc
.type
)
455 case RESOURCE_TYPE_RENDER_TARGET
:
456 view
= get_cpu_rtv_handle(test_context
, runner
->rtv_heap
, resource
->desc
.slot
);
457 ID3D12GraphicsCommandList_ClearRenderTargetView(command_list
, view
, (const float *)clear_value
, 0, NULL
);
460 case RESOURCE_TYPE_DEPTH_STENCIL
:
461 view
= get_cpu_dsv_handle(test_context
, runner
->dsv_heap
, 0);
462 ID3D12GraphicsCommandList_ClearDepthStencilView(command_list
, view
,
463 D3D12_CLEAR_FLAG_DEPTH
, clear_value
->x
, 0, 0, NULL
);
467 fatal_error("Clears are not implemented for resource type %u.\n", resource
->desc
.type
);
470 hr
= ID3D12GraphicsCommandList_Close(command_list
);
471 ok(hr
== S_OK
, "Failed to close command list, hr %#x.\n", hr
);
472 exec_command_list(queue
, command_list
);
473 wait_queue_idle(device
, queue
);
474 reset_command_list(command_list
, test_context
->allocator
);
477 static D3D12_PRIMITIVE_TOPOLOGY_TYPE
d3d12_primitive_topology_type_from_primitive_topology(
478 D3D_PRIMITIVE_TOPOLOGY primitive_topology
)
480 switch (primitive_topology
)
482 case D3D_PRIMITIVE_TOPOLOGY_POINTLIST
:
483 return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT
;
484 case D3D_PRIMITIVE_TOPOLOGY_LINELIST
:
485 case D3D_PRIMITIVE_TOPOLOGY_LINESTRIP
:
486 case D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ
:
487 case D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ
:
488 return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE
;
489 case D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST
:
490 case D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP
:
491 case D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ
:
492 case D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ
:
493 return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE
;
495 if (primitive_topology
>= D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST
496 && primitive_topology
<= D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST
)
497 return D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH
;
498 fatal_error("Unhandled primitive topology %u.\n", primitive_topology
);
502 static D3D12_INPUT_ELEMENT_DESC
*create_element_descs(const struct d3d12_shader_runner
*runner
)
504 D3D12_INPUT_ELEMENT_DESC
*input_element_descs
= calloc(runner
->r
.input_element_count
, sizeof(*input_element_descs
));
505 for (size_t i
= 0; i
< runner
->r
.input_element_count
; ++i
)
507 const struct input_element
*element
= &runner
->r
.input_elements
[i
];
508 D3D12_INPUT_ELEMENT_DESC
*desc
= &input_element_descs
[i
];
510 desc
->SemanticName
= element
->name
;
511 desc
->SemanticIndex
= element
->index
;
512 desc
->Format
= element
->format
;
513 desc
->InputSlot
= element
->slot
;
514 desc
->AlignedByteOffset
= D3D12_APPEND_ALIGNED_ELEMENT
;
515 desc
->InputSlotClass
= D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA
;
518 return input_element_descs
;
521 static ID3D12PipelineState
*create_pipeline(struct d3d12_shader_runner
*runner
,
522 D3D12_PRIMITIVE_TOPOLOGY primitive_topology
, ID3D10Blob
*vs_code
, ID3D10Blob
*ps_code
,
523 ID3D10Blob
*hs_code
, ID3D10Blob
*ds_code
, ID3D10Blob
*gs_code
)
525 struct test_context
*test_context
= &runner
->test_context
;
526 D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc
= {0};
527 D3D12_INPUT_ELEMENT_DESC
*input_element_descs
;
528 ID3D12Device
*device
= test_context
->device
;
529 unsigned int sample_count
= 1;
530 ID3D12PipelineState
*pso
;
533 for (size_t i
= 0; i
< runner
->r
.resource_count
; ++i
)
535 struct d3d12_resource
*resource
= d3d12_resource(runner
->r
.resources
[i
]);
537 if (resource
->r
.desc
.type
== RESOURCE_TYPE_RENDER_TARGET
)
539 pso_desc
.RTVFormats
[resource
->r
.desc
.slot
] = resource
->r
.desc
.format
;
540 pso_desc
.NumRenderTargets
= max(pso_desc
.NumRenderTargets
, resource
->r
.desc
.slot
+ 1);
541 pso_desc
.BlendState
.RenderTarget
[resource
->r
.desc
.slot
].RenderTargetWriteMask
= D3D12_COLOR_WRITE_ENABLE_ALL
;
542 if (resource
->r
.desc
.sample_count
)
543 sample_count
= resource
->r
.desc
.sample_count
;
545 else if (resource
->r
.desc
.type
== RESOURCE_TYPE_DEPTH_STENCIL
)
547 assert(!resource
->r
.desc
.slot
);
548 pso_desc
.DSVFormat
= resource
->r
.desc
.format
;
549 pso_desc
.DepthStencilState
.DepthEnable
= true;
550 pso_desc
.DepthStencilState
.DepthWriteMask
= D3D12_DEPTH_WRITE_MASK_ALL
;
551 pso_desc
.DepthStencilState
.DepthFunc
= runner
->r
.depth_func
;
555 pso_desc
.VS
.pShaderBytecode
= ID3D10Blob_GetBufferPointer(vs_code
);
556 pso_desc
.VS
.BytecodeLength
= ID3D10Blob_GetBufferSize(vs_code
);
557 pso_desc
.PS
.pShaderBytecode
= ID3D10Blob_GetBufferPointer(ps_code
);
558 pso_desc
.PS
.BytecodeLength
= ID3D10Blob_GetBufferSize(ps_code
);
561 pso_desc
.HS
.pShaderBytecode
= ID3D10Blob_GetBufferPointer(hs_code
);
562 pso_desc
.HS
.BytecodeLength
= ID3D10Blob_GetBufferSize(hs_code
);
566 pso_desc
.DS
.pShaderBytecode
= ID3D10Blob_GetBufferPointer(ds_code
);
567 pso_desc
.DS
.BytecodeLength
= ID3D10Blob_GetBufferSize(ds_code
);
571 pso_desc
.GS
.pShaderBytecode
= ID3D10Blob_GetBufferPointer(gs_code
);
572 pso_desc
.GS
.BytecodeLength
= ID3D10Blob_GetBufferSize(gs_code
);
574 pso_desc
.PrimitiveTopologyType
= d3d12_primitive_topology_type_from_primitive_topology(primitive_topology
);
575 pso_desc
.RasterizerState
.FillMode
= D3D12_FILL_MODE_SOLID
;
576 pso_desc
.RasterizerState
.CullMode
= D3D12_CULL_MODE_NONE
;
577 pso_desc
.SampleDesc
.Count
= sample_count
;
578 pso_desc
.SampleMask
= runner
->r
.sample_mask
? runner
->r
.sample_mask
: ~(UINT
)0;
579 pso_desc
.pRootSignature
= test_context
->root_signature
;
581 input_element_descs
= create_element_descs(runner
);
582 pso_desc
.InputLayout
.pInputElementDescs
= input_element_descs
;
583 pso_desc
.InputLayout
.NumElements
= runner
->r
.input_element_count
;
585 hr
= ID3D12Device_CreateGraphicsPipelineState(device
, &pso_desc
,
586 &IID_ID3D12PipelineState
, (void **)&pso
);
587 todo_if(runner
->r
.is_todo
) ok(hr
== S_OK
, "Failed to create state, hr %#x.\n", hr
);
589 free(input_element_descs
);
597 static ID3D12PipelineState
*create_pipeline_device2(struct d3d12_shader_runner
*runner
,
598 D3D12_PRIMITIVE_TOPOLOGY primitive_topology
, ID3D10Blob
*vs_code
, ID3D10Blob
*ps_code
,
599 ID3D10Blob
*hs_code
, ID3D10Blob
*ds_code
, ID3D10Blob
*gs_code
)
601 struct test_context
*test_context
= &runner
->test_context
;
602 ID3D12Device2
*device2
= test_context
->device2
;
603 D3D12_PIPELINE_STATE_STREAM_DESC pipeline_desc
;
604 D3D12_INPUT_ELEMENT_DESC
*input_element_descs
;
605 unsigned int sample_count
= 1;
606 ID3D12PipelineState
*pso
;
611 struct d3d12_root_signature_subobject root_signature
;
612 struct d3d12_shader_bytecode_subobject vs
;
613 struct d3d12_shader_bytecode_subobject ps
;
614 struct d3d12_shader_bytecode_subobject hs
;
615 struct d3d12_shader_bytecode_subobject ds
;
616 struct d3d12_shader_bytecode_subobject gs
;
617 struct d3d12_render_target_formats_subobject rtv_format
;
618 struct d3d12_blend_subobject blend
;
619 struct d3d12_depth_stencil_format_subobject dsv_format
;
620 struct d3d12_depth_stencil1_subobject dsv
;
621 struct d3d12_rasterizer_subobject rasterizer
;
622 struct d3d12_primitive_topology_subobject topology
;
623 struct d3d12_sample_desc_subobject sample_desc
;
624 struct d3d12_sample_mask_subobject sample_mask
;
625 struct d3d12_input_layout_subobject input_layout
;
631 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE
,
632 .root_signature
= test_context
->root_signature
,
636 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS
,
637 .shader_bytecode
= shader_bytecode_from_blob(vs_code
),
641 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS
,
642 .shader_bytecode
= shader_bytecode_from_blob(ps_code
),
646 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_HS
,
647 .shader_bytecode
= hs_code
? shader_bytecode_from_blob(hs_code
) : (D3D12_SHADER_BYTECODE
) {0},
651 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DS
,
652 .shader_bytecode
= ds_code
? shader_bytecode_from_blob(ds_code
) : (D3D12_SHADER_BYTECODE
) {0},
656 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_GS
,
657 .shader_bytecode
= gs_code
? shader_bytecode_from_blob(gs_code
) : (D3D12_SHADER_BYTECODE
) {0},
661 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS
,
665 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND
,
669 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT
,
673 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1
,
677 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER
,
680 .FillMode
= D3D12_FILL_MODE_SOLID
,
681 .CullMode
= D3D12_CULL_MODE_NONE
,
686 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY
,
687 .primitive_topology_type
= d3d12_primitive_topology_type_from_primitive_topology(primitive_topology
),
691 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC
,
695 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK
,
696 .sample_mask
= runner
->r
.sample_mask
? runner
->r
.sample_mask
: ~(UINT
)0,
700 .type
= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT
,
707 input_element_descs
= create_element_descs(runner
);
708 pipeline
.input_layout
.input_layout
.NumElements
= runner
->r
.input_element_count
;
709 pipeline
.input_layout
.input_layout
.pInputElementDescs
= input_element_descs
;
711 for (size_t i
= 0; i
< runner
->r
.resource_count
; ++i
)
713 struct d3d12_resource
*resource
= d3d12_resource(runner
->r
.resources
[i
]);
715 if (resource
->r
.desc
.type
== RESOURCE_TYPE_RENDER_TARGET
)
717 pipeline
.rtv_format
.render_target_formats
.RTFormats
[resource
->r
.desc
.slot
] = resource
->r
.desc
.format
;
718 pipeline
.rtv_format
.render_target_formats
.NumRenderTargets
=
719 max(pipeline
.rtv_format
.render_target_formats
.NumRenderTargets
, resource
->r
.desc
.slot
+ 1);
720 pipeline
.blend
.blend_desc
.RenderTarget
[resource
->r
.desc
.slot
].RenderTargetWriteMask
=
721 D3D12_COLOR_WRITE_ENABLE_ALL
;
722 if (resource
->r
.desc
.sample_count
)
723 sample_count
= resource
->r
.desc
.sample_count
;
725 else if (resource
->r
.desc
.type
== RESOURCE_TYPE_DEPTH_STENCIL
)
727 assert(!resource
->r
.desc
.slot
);
728 pipeline
.dsv_format
.depth_stencil_format
= resource
->r
.desc
.format
;
729 pipeline
.dsv
.depth_stencil_desc
.DepthEnable
= true;
730 pipeline
.dsv
.depth_stencil_desc
.DepthWriteMask
= D3D12_DEPTH_WRITE_MASK_ALL
;
731 pipeline
.dsv
.depth_stencil_desc
.DepthFunc
= runner
->r
.depth_func
;
732 pipeline
.dsv
.depth_stencil_desc
.DepthBoundsTestEnable
= runner
->r
.depth_bounds
;
736 pipeline
.sample_desc
.sample_desc
.Count
= sample_count
;
738 pipeline_desc
.SizeInBytes
= sizeof(pipeline
);
739 pipeline_desc
.pPipelineStateSubobjectStream
= &pipeline
;
741 hr
= ID3D12Device2_CreatePipelineState(device2
, &pipeline_desc
, &IID_ID3D12PipelineState
, (void **)&pso
);
742 todo_if(runner
->r
.is_todo
) ok(hr
== S_OK
, "Failed to create state, hr %#x.\n", hr
);
744 free(input_element_descs
);
751 static bool d3d12_runner_draw(struct shader_runner
*r
,
752 D3D_PRIMITIVE_TOPOLOGY primitive_topology
, unsigned int vertex_count
, unsigned int instance_count
)
754 struct d3d12_shader_runner
*runner
= d3d12_shader_runner(r
);
755 struct test_context
*test_context
= &runner
->test_context
;
757 ID3D10Blob
*vs_code
, *ps_code
, *hs_code
= NULL
, *ds_code
= NULL
, *gs_code
= NULL
;
758 D3D12_CPU_DESCRIPTOR_HANDLE rtvs
[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT
] = {0};
759 ID3D12GraphicsCommandList1
*command_list1
= test_context
->list1
;
760 unsigned int uniform_index
, fb_width
, fb_height
, rtv_count
= 0;
761 ID3D12GraphicsCommandList
*command_list
= test_context
->list
;
762 ID3D12CommandQueue
*queue
= test_context
->queue
;
763 ID3D12Device
*device
= test_context
->device
;
764 D3D12_CPU_DESCRIPTOR_HANDLE dsv
= {0};
765 ID3D12PipelineState
*pso
;
770 ps_code
= compile_hlsl(&runner
->r
, SHADER_TYPE_PS
);
771 vs_code
= compile_hlsl(&runner
->r
, SHADER_TYPE_VS
);
772 succeeded
= ps_code
&& vs_code
;
774 if (runner
->r
.shader_source
[SHADER_TYPE_HS
])
776 hs_code
= compile_hlsl(&runner
->r
, SHADER_TYPE_HS
);
777 succeeded
= succeeded
&& hs_code
;
779 if (runner
->r
.shader_source
[SHADER_TYPE_DS
])
781 ds_code
= compile_hlsl(&runner
->r
, SHADER_TYPE_DS
);
782 succeeded
= succeeded
&& ds_code
;
784 if (runner
->r
.shader_source
[SHADER_TYPE_GS
])
786 gs_code
= compile_hlsl(&runner
->r
, SHADER_TYPE_GS
);
787 succeeded
= succeeded
&& gs_code
;
790 todo_if(runner
->r
.is_todo
&& runner
->r
.minimum_shader_model
< SHADER_MODEL_6_0
)
791 ok(succeeded
, "Failed to compile shaders.\n");
796 ID3D10Blob_Release(ps_code
);
798 ID3D10Blob_Release(vs_code
);
800 ID3D10Blob_Release(hs_code
);
802 ID3D10Blob_Release(ds_code
);
804 ID3D10Blob_Release(gs_code
);
808 if (test_context
->root_signature
)
809 ID3D12RootSignature_Release(test_context
->root_signature
);
810 test_context
->root_signature
= d3d12_runner_create_root_signature(runner
,
811 queue
, test_context
->allocator
, command_list
, &uniform_index
);
813 pso
= test_context
->device2
814 ? create_pipeline_device2(runner
, primitive_topology
, vs_code
, ps_code
, hs_code
, ds_code
, gs_code
)
815 : create_pipeline(runner
, primitive_topology
, vs_code
, ps_code
, hs_code
, ds_code
, gs_code
);
817 ID3D10Blob_Release(vs_code
);
818 ID3D10Blob_Release(ps_code
);
820 ID3D10Blob_Release(hs_code
);
822 ID3D10Blob_Release(ds_code
);
824 ID3D10Blob_Release(gs_code
);
829 add_pso(test_context
, pso
);
833 ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list
, test_context
->root_signature
);
834 if (runner
->r
.uniform_count
)
835 ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list
, uniform_index
,
836 runner
->r
.uniform_count
, runner
->r
.uniforms
, 0);
838 ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list
, 1, &runner
->heap
);
839 for (i
= 0; i
< runner
->r
.resource_count
; ++i
)
841 struct d3d12_resource
*resource
= d3d12_resource(runner
->r
.resources
[i
]);
842 D3D12_VERTEX_BUFFER_VIEW vbv
;
844 switch (resource
->r
.desc
.type
)
846 case RESOURCE_TYPE_RENDER_TARGET
:
847 rtvs
[resource
->r
.desc
.slot
] = get_cpu_rtv_handle(test_context
, runner
->rtv_heap
, resource
->r
.desc
.slot
);
848 rtv_count
= max(rtv_count
, resource
->r
.desc
.slot
+ 1);
849 if (resource
->r
.desc
.width
< fb_width
)
850 fb_width
= resource
->r
.desc
.width
;
851 if (resource
->r
.desc
.height
< fb_height
)
852 fb_height
= resource
->r
.desc
.height
;
855 case RESOURCE_TYPE_DEPTH_STENCIL
:
856 dsv
= get_cpu_dsv_handle(test_context
, runner
->dsv_heap
, 0);
857 if (resource
->r
.desc
.width
< fb_width
)
858 fb_width
= resource
->r
.desc
.width
;
859 if (resource
->r
.desc
.height
< fb_height
)
860 fb_height
= resource
->r
.desc
.height
;
863 case RESOURCE_TYPE_TEXTURE
:
864 if (resource
->descriptor_range
.NumDescriptors
)
865 ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list
, resource
->root_index
,
866 get_gpu_descriptor_handle(test_context
, runner
->heap
, resource
->r
.desc
.slot
));
869 case RESOURCE_TYPE_UAV
:
870 if (resource
->descriptor_range
.NumDescriptors
)
871 ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list
, resource
->root_index
,
872 get_gpu_descriptor_handle(test_context
, runner
->heap
, resource
->r
.desc
.slot
+ MAX_RESOURCES
));
875 case RESOURCE_TYPE_VERTEX_BUFFER
:
876 vbv
.BufferLocation
= ID3D12Resource_GetGPUVirtualAddress(resource
->resource
);
877 vbv
.StrideInBytes
= get_vb_stride(&runner
->r
, resource
->r
.desc
.slot
);
878 vbv
.SizeInBytes
= resource
->r
.desc
.width
;
880 ID3D12GraphicsCommandList_IASetVertexBuffers(command_list
, resource
->r
.desc
.slot
, 1, &vbv
);
885 ID3D12GraphicsCommandList_OMSetRenderTargets(command_list
, rtv_count
, rtvs
, false, dsv
.ptr
? &dsv
: NULL
);
887 if (runner
->r
.depth_bounds
)
888 ID3D12GraphicsCommandList1_OMSetDepthBounds(command_list1
, runner
->r
.depth_min
, runner
->r
.depth_max
);
889 set_rect(&test_context
->scissor_rect
, 0, 0, fb_width
, fb_height
);
890 ID3D12GraphicsCommandList_RSSetScissorRects(command_list
, 1, &test_context
->scissor_rect
);
891 set_viewport(&test_context
->viewport
, 0.0f
, 0.0f
, fb_width
, fb_height
, 0.0f
, 1.0f
);
892 ID3D12GraphicsCommandList_RSSetViewports(command_list
, 1, &test_context
->viewport
);
893 ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list
, primitive_topology
);
894 ID3D12GraphicsCommandList_SetPipelineState(command_list
, pso
);
895 ID3D12GraphicsCommandList_DrawInstanced(command_list
, vertex_count
, instance_count
, 0, 0);
897 /* Finish the command list so that we can destroy objects. */
898 hr
= ID3D12GraphicsCommandList_Close(command_list
);
899 ok(hr
== S_OK
, "Failed to close command list, hr %#x.\n", hr
);
900 exec_command_list(queue
, command_list
);
901 wait_queue_idle(device
, queue
);
902 reset_command_list(command_list
, test_context
->allocator
);
907 static bool d3d12_runner_copy(struct shader_runner
*r
, struct resource
*src
, struct resource
*dst
)
909 struct d3d12_shader_runner
*runner
= d3d12_shader_runner(r
);
910 struct test_context
*context
= &runner
->test_context
;
911 struct d3d12_resource
*s
= d3d12_resource(src
);
912 struct d3d12_resource
*d
= d3d12_resource(dst
);
913 D3D12_RESOURCE_STATES src_state
, dst_state
;
916 src_state
= resource_get_state(src
);
917 dst_state
= resource_get_state(dst
);
919 transition_resource_state(context
->list
, s
->resource
, src_state
, D3D12_RESOURCE_STATE_COPY_SOURCE
);
920 transition_resource_state(context
->list
, d
->resource
, dst_state
, D3D12_RESOURCE_STATE_COPY_DEST
);
921 ID3D12GraphicsCommandList_CopyResource(context
->list
, d
->resource
, s
->resource
);
922 transition_resource_state(context
->list
, d
->resource
, D3D12_RESOURCE_STATE_COPY_DEST
, dst_state
);
923 transition_resource_state(context
->list
, s
->resource
, D3D12_RESOURCE_STATE_COPY_SOURCE
, src_state
);
925 hr
= ID3D12GraphicsCommandList_Close(context
->list
);
926 ok(hr
== S_OK
, "Failed to close command list, hr %#x.\n", hr
);
927 exec_command_list(context
->queue
, context
->list
);
928 wait_queue_idle(context
->device
, context
->queue
);
929 reset_command_list(context
->list
, context
->allocator
);
934 static struct resource_readback
*d3d12_runner_get_resource_readback(struct shader_runner
*r
,
935 struct resource
*res
, unsigned int sub_resource_idx
)
937 struct d3d12_shader_runner
*runner
= d3d12_shader_runner(r
);
938 struct test_context
*test_context
= &runner
->test_context
;
939 struct d3d12_resource_readback
*rb
= malloc(sizeof(*rb
));
940 struct d3d12_resource
*resource
= d3d12_resource(res
);
941 D3D12_RESOURCE_STATES state
;
943 state
= resource_get_state(res
);
944 get_resource_readback_with_command_list_and_states(resource
->resource
,
945 sub_resource_idx
, rb
, test_context
->queue
, test_context
->list
, state
, state
);
946 reset_command_list(test_context
->list
, test_context
->allocator
);
951 static void d3d12_runner_release_readback(struct shader_runner
*r
, struct resource_readback
*rb
)
953 struct d3d12_resource_readback
*d3d12_rb
= CONTAINING_RECORD(rb
, struct d3d12_resource_readback
, rb
);
955 release_resource_readback(d3d12_rb
);
959 static const struct shader_runner_ops d3d12_runner_ops
=
961 .create_resource
= d3d12_runner_create_resource
,
962 .destroy_resource
= d3d12_runner_destroy_resource
,
963 .dispatch
= d3d12_runner_dispatch
,
964 .clear
= d3d12_runner_clear
,
965 .draw
= d3d12_runner_draw
,
966 .copy
= d3d12_runner_copy
,
967 .get_resource_readback
= d3d12_runner_get_resource_readback
,
968 .release_readback
= d3d12_runner_release_readback
,
971 static uint32_t get_format_support(ID3D12Device
*device
, enum DXGI_FORMAT format
)
973 D3D12_FEATURE_DATA_FORMAT_SUPPORT format_support
= {.Format
= format
};
977 hr
= ID3D12Device_CheckFeatureSupport(device
, D3D12_FEATURE_FORMAT_SUPPORT
,
978 &format_support
, sizeof(format_support
));
979 ok(hr
== S_OK
, "Failed to query format support, hr %#x.\n", hr
);
981 if (format_support
.Support2
& D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD
)
982 ret
|= FORMAT_CAP_UAV_LOAD
;
987 static void d3d12_runner_init_caps(struct d3d12_shader_runner
*runner
,
988 enum shader_model minimum_shader_model
, enum shader_model maximum_shader_model
)
990 ID3D12Device
*device
= runner
->test_context
.device
;
991 D3D12_FEATURE_DATA_D3D12_OPTIONS4 options4
;
992 D3D12_FEATURE_DATA_D3D12_OPTIONS2 options2
;
993 D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1
;
994 D3D12_FEATURE_DATA_D3D12_OPTIONS options
;
997 static const enum DXGI_FORMAT formats
[] =
999 DXGI_FORMAT_R32_FLOAT
,
1000 DXGI_FORMAT_R32_UINT
,
1001 DXGI_FORMAT_R32_SINT
,
1002 DXGI_FORMAT_R32G32B32A32_FLOAT
,
1003 DXGI_FORMAT_R32G32B32A32_UINT
,
1004 DXGI_FORMAT_R32G32B32A32_SINT
,
1005 DXGI_FORMAT_R16G16B16A16_FLOAT
,
1006 DXGI_FORMAT_R16G16B16A16_UINT
,
1007 DXGI_FORMAT_R16G16B16A16_SINT
,
1008 DXGI_FORMAT_R32G32_FLOAT
,
1009 DXGI_FORMAT_R8G8B8A8_UNORM
,
1010 DXGI_FORMAT_R8G8B8A8_UINT
,
1011 DXGI_FORMAT_R8G8B8A8_SINT
,
1012 DXGI_FORMAT_R16_FLOAT
,
1013 DXGI_FORMAT_R16_UINT
,
1014 DXGI_FORMAT_R16_SINT
,
1015 DXGI_FORMAT_R8_UNORM
,
1016 DXGI_FORMAT_R8_UINT
,
1017 DXGI_FORMAT_R8_SINT
,
1020 hr
= ID3D12Device_CheckFeatureSupport(device
, D3D12_FEATURE_D3D12_OPTIONS
, &options
, sizeof(options
));
1021 ok(hr
== S_OK
, "Failed to check feature options support, hr %#x.\n", hr
);
1022 hr
= ID3D12Device_CheckFeatureSupport(device
, D3D12_FEATURE_D3D12_OPTIONS1
, &options1
, sizeof(options1
));
1023 ok(hr
== S_OK
, "Failed to check feature options1 support, hr %#x.\n", hr
);
1024 hr
= ID3D12Device_CheckFeatureSupport(device
, D3D12_FEATURE_D3D12_OPTIONS2
, &options2
, sizeof(options2
));
1025 ok(hr
== S_OK
, "Failed to check feature options2 support, hr %#x.\n", hr
);
1026 hr
= ID3D12Device_CheckFeatureSupport(device
, D3D12_FEATURE_D3D12_OPTIONS4
, &options4
, sizeof(options4
));
1027 ok(hr
== S_OK
, "Failed to check feature options4 support, hr %#x.\n", hr
);
1029 #ifdef VKD3D_CROSSTEST
1030 runner
->caps
.runner
= "d3d12.dll";
1032 runner
->caps
.runner
= "vkd3d";
1034 runner
->caps
.minimum_shader_model
= minimum_shader_model
;
1035 runner
->caps
.maximum_shader_model
= maximum_shader_model
;
1036 runner
->caps
.shader_caps
[SHADER_CAP_DEPTH_BOUNDS
] = options2
.DepthBoundsTestSupported
;
1037 runner
->caps
.shader_caps
[SHADER_CAP_FLOAT64
] = options
.DoublePrecisionFloatShaderOps
;
1038 runner
->caps
.shader_caps
[SHADER_CAP_GEOMETRY_SHADER
] = true;
1039 runner
->caps
.shader_caps
[SHADER_CAP_INT64
] = options1
.Int64ShaderOps
;
1040 runner
->caps
.shader_caps
[SHADER_CAP_ROV
] = options
.ROVsSupported
;
1041 runner
->caps
.shader_caps
[SHADER_CAP_RT_VP_ARRAY_INDEX
]
1042 = options
.VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation
;
1043 runner
->caps
.shader_caps
[SHADER_CAP_WAVE_OPS
] = options1
.WaveOps
;
1044 runner
->caps
.shader_caps
[SHADER_CAP_NATIVE_16_BIT
] = options4
.Native16BitShaderOpsSupported
;
1046 runner
->caps
.tag_count
= 0;
1047 runner
->caps
.tags
[runner
->caps
.tag_count
++] = "d3d12";
1048 if (is_mvk_device(device
))
1050 runner
->caps
.tags
[runner
->caps
.tag_count
++] = "mvk";
1054 if (is_llvmpipe_device(device
))
1055 runner
->caps
.tags
[runner
->caps
.tag_count
++] = "llvmpipe";
1056 if (is_mesa_device_lt(device
, 23, 3, 0))
1057 runner
->caps
.tags
[runner
->caps
.tag_count
++] = "mesa<23.3";
1060 for (unsigned int i
= 0; i
< ARRAY_SIZE(formats
); ++i
)
1062 runner
->caps
.format_caps
[formats
[i
]] = get_format_support(device
, formats
[i
]);
1066 static bool device_supports_shader_model_6_0(ID3D12Device
*device
)
1068 D3D12_FEATURE_DATA_SHADER_MODEL sm
= {D3D_SHADER_MODEL_6_0
};
1071 hr
= ID3D12Device_CheckFeatureSupport(device
, D3D12_FEATURE_SHADER_MODEL
, &sm
, sizeof(sm
));
1072 ok(hr
== S_OK
, "Failed to check feature shader model support, hr %#x.\n", hr
);
1073 return sm
.HighestShaderModel
>= D3D_SHADER_MODEL_6_0
;
1076 static void run_shader_tests_for_model_range(void *dxc_compiler
,
1077 enum shader_model minimum_shader_model
, enum shader_model maximum_shader_model
)
1079 static const struct test_context_desc desc
=
1081 .rt_width
= RENDER_TARGET_WIDTH
,
1082 .rt_height
= RENDER_TARGET_HEIGHT
,
1083 .no_root_signature
= true,
1084 .rt_format
= DXGI_FORMAT_R32G32B32A32_FLOAT
,
1086 struct d3d12_shader_runner runner
= {0};
1087 ID3D12Device
*device
;
1090 if (!init_test_context(&runner
.test_context
, &desc
))
1092 device
= runner
.test_context
.device
;
1094 if (minimum_shader_model
>= SHADER_MODEL_6_0
&& !device_supports_shader_model_6_0(device
))
1096 #ifdef VKD3D_CROSSTEST
1097 skip("The device does not support shader model 6.0.\n");
1099 skip("DXIL support is not enabled. If this is unintentional, "
1100 "add -DVKD3D_SHADER_UNSUPPORTED_DXIL to CPPFLAGS.\n");
1102 destroy_test_context(&runner
.test_context
);
1106 d3d12_runner_init_caps(&runner
, minimum_shader_model
, maximum_shader_model
);
1108 runner
.compute_queue
= create_command_queue(device
,
1109 D3D12_COMMAND_LIST_TYPE_COMPUTE
, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL
);
1111 hr
= ID3D12Device_CreateCommandAllocator(device
, D3D12_COMMAND_LIST_TYPE_COMPUTE
,
1112 &IID_ID3D12CommandAllocator
, (void **)&runner
.compute_allocator
);
1113 ok(hr
== S_OK
, "Failed to create command allocator, hr %#x.\n", hr
);
1115 hr
= ID3D12Device_CreateCommandList(device
, 0, D3D12_COMMAND_LIST_TYPE_COMPUTE
,
1116 runner
.compute_allocator
, NULL
, &IID_ID3D12GraphicsCommandList
, (void **)&runner
.compute_list
);
1117 ok(hr
== S_OK
, "Failed to create command list, hr %#x.\n", hr
);
1119 run_shader_tests(&runner
.r
, &runner
.caps
, &d3d12_runner_ops
, dxc_compiler
);
1121 ID3D12GraphicsCommandList_Release(runner
.compute_list
);
1122 ID3D12CommandAllocator_Release(runner
.compute_allocator
);
1123 ID3D12CommandQueue_Release(runner
.compute_queue
);
1125 ID3D12DescriptorHeap_Release(runner
.heap
);
1126 if (runner
.rtv_heap
)
1127 ID3D12DescriptorHeap_Release(runner
.rtv_heap
);
1128 if (runner
.dsv_heap
)
1129 ID3D12DescriptorHeap_Release(runner
.dsv_heap
);
1130 destroy_test_context(&runner
.test_context
);
1133 void run_shader_tests_d3d12(void *dxc_compiler
)
1135 enable_d3d12_debug_layer();
1136 init_adapter_info();
1138 run_shader_tests_for_model_range(NULL
, SHADER_MODEL_4_0
, SHADER_MODEL_5_1
);
1141 run_shader_tests_for_model_range(dxc_compiler
, SHADER_MODEL_6_0
, SHADER_MODEL_6_2
);