2 * Copyright 2008 Henri Verbeet for CodeWeavers
3 * Copyright 2015 Józef Kucia for CodeWeavers
4 * Copyright 2021 Zebediah Figura for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #define VKD3D_TEST_NO_DEFS
28 #define __vkd3d_d3dcommon_h__
29 #define __vkd3d_dxgibase_h__
30 #define __vkd3d_dxgiformat_h__
31 #include "vkd3d_d3dcompiler.h"
32 #include "shader_runner.h"
33 #include "vkd3d_test.h"
35 static HRESULT (WINAPI
*pCreateDXGIFactory1
)(REFIID iid
, void **factory
);
37 static HRESULT (WINAPI
*pD3D11CreateDevice
)(IDXGIAdapter
*adapter
, D3D_DRIVER_TYPE driver_type
,
38 HMODULE swrast
, UINT flags
, const D3D_FEATURE_LEVEL
*feature_levels
, UINT levels
,
39 UINT sdk_version
, ID3D11Device
**device_out
, D3D_FEATURE_LEVEL
*obtained_feature_level
,
40 ID3D11DeviceContext
**immediate_context
);
46 ID3D11Resource
*resource
;
48 ID3D11Texture2D
*texture
;
49 ID3D11RenderTargetView
*rtv
;
50 ID3D11DepthStencilView
*dsv
;
51 ID3D11ShaderResourceView
*srv
;
52 ID3D11UnorderedAccessView
*uav
;
56 static struct d3d11_resource
*d3d11_resource(struct resource
*r
)
58 return CONTAINING_RECORD(r
, struct d3d11_resource
, r
);
61 struct d3d11_shader_runner
63 struct shader_runner r
;
64 struct shader_runner_caps caps
;
68 IDXGISwapChain
*swapchain
;
69 ID3D11DeviceContext
*immediate_context
;
70 ID3D11RasterizerState
*rasterizer_state
;
73 static struct d3d11_shader_runner
*d3d11_shader_runner(struct shader_runner
*r
)
75 return CONTAINING_RECORD(r
, struct d3d11_shader_runner
, r
);
78 static void set_viewport(ID3D11DeviceContext
*context
, float x
, float y
,
79 float width
, float height
, float min_depth
, float max_depth
)
87 .MinDepth
= min_depth
,
88 .MaxDepth
= max_depth
,
91 ID3D11DeviceContext_RSSetViewports(context
, 1, &vp
);
94 static IDXGIAdapter
*create_adapter(void)
96 IDXGIFactory4
*factory4
;
97 IDXGIFactory
*factory
;
98 IDXGIAdapter
*adapter
;
101 if (!pCreateDXGIFactory1
)
103 trace("CreateDXGIFactory1() is not available.\n");
107 if (FAILED(hr
= pCreateDXGIFactory1(&IID_IDXGIFactory
, (void **)&factory
)))
109 trace("Failed to create IDXGIFactory, hr %#lx.\n", hr
);
114 if (test_options
.use_warp_device
)
116 if (SUCCEEDED(hr
= IDXGIFactory_QueryInterface(factory
, &IID_IDXGIFactory4
, (void **)&factory4
)))
118 hr
= IDXGIFactory4_EnumWarpAdapter(factory4
, &IID_IDXGIAdapter
, (void **)&adapter
);
119 IDXGIFactory4_Release(factory4
);
123 trace("Failed to get IDXGIFactory4, hr %#lx.\n", hr
);
128 hr
= IDXGIFactory_EnumAdapters(factory
, test_options
.adapter_idx
, &adapter
);
130 IDXGIFactory_Release(factory
);
132 trace("Failed to get adapter, hr %#lx.\n", hr
);
136 static void init_adapter_info(void)
138 char name
[MEMBER_SIZE(DXGI_ADAPTER_DESC
, Description
)];
139 IDXGIAdapter
*adapter
;
140 DXGI_ADAPTER_DESC desc
;
144 if (!(adapter
= create_adapter()))
147 hr
= IDXGIAdapter_GetDesc(adapter
, &desc
);
148 ok(hr
== S_OK
, "Failed to get adapter desc, hr %#lx.\n", hr
);
150 /* FIXME: Use debugstr_w(). */
151 for (i
= 0; i
< ARRAY_SIZE(desc
.Description
) && isprint(desc
.Description
[i
]); ++i
)
152 name
[i
] = desc
.Description
[i
];
153 name
[min(i
, ARRAY_SIZE(name
) - 1)] = '\0';
155 trace("Adapter: %s, %04x:%04x.\n", name
, desc
.VendorId
, desc
.DeviceId
);
157 if (desc
.VendorId
== 0x1414 && desc
.DeviceId
== 0x008c)
159 trace("Using WARP device.\n");
160 test_options
.use_warp_device
= true;
163 IDXGIAdapter_Release(adapter
);
166 static ID3D11Device
*create_device(void)
168 static const D3D_FEATURE_LEVEL feature_level
[] =
170 D3D_FEATURE_LEVEL_11_0
,
171 D3D_FEATURE_LEVEL_10_1
,
172 D3D_FEATURE_LEVEL_10_0
,
174 IDXGIAdapter
*adapter
;
175 ID3D11Device
*device
;
179 if (test_options
.enable_debug_layer
)
180 flags
|= D3D11_CREATE_DEVICE_DEBUG
;
182 if ((adapter
= create_adapter()))
184 hr
= pD3D11CreateDevice(adapter
, D3D_DRIVER_TYPE_UNKNOWN
, NULL
, flags
,
185 feature_level
, ARRAY_SIZE(feature_level
), D3D11_SDK_VERSION
, &device
, NULL
, NULL
);
186 IDXGIAdapter_Release(adapter
);
187 return SUCCEEDED(hr
) ? device
: NULL
;
190 if (SUCCEEDED(pD3D11CreateDevice(NULL
, D3D_DRIVER_TYPE_HARDWARE
, NULL
, flags
,
191 feature_level
, ARRAY_SIZE(feature_level
), D3D11_SDK_VERSION
, &device
, NULL
, NULL
)))
193 if (SUCCEEDED(pD3D11CreateDevice(NULL
, D3D_DRIVER_TYPE_WARP
, NULL
, flags
,
194 feature_level
, ARRAY_SIZE(feature_level
), D3D11_SDK_VERSION
, &device
, NULL
, NULL
)))
196 if (SUCCEEDED(pD3D11CreateDevice(NULL
, D3D_DRIVER_TYPE_REFERENCE
, NULL
, flags
,
197 feature_level
, ARRAY_SIZE(feature_level
), D3D11_SDK_VERSION
, &device
, NULL
, NULL
)))
203 static IDXGISwapChain
*create_swapchain(ID3D11Device
*device
, HWND window
)
205 DXGI_SWAP_CHAIN_DESC dxgi_desc
;
206 IDXGISwapChain
*swapchain
;
207 IDXGIDevice
*dxgi_device
;
208 IDXGIAdapter
*adapter
;
209 IDXGIFactory
*factory
;
212 hr
= ID3D11Device_QueryInterface(device
, &IID_IDXGIDevice
, (void **)&dxgi_device
);
213 ok(hr
== S_OK
, "Failed to get DXGI device, hr %#lx.\n", hr
);
214 hr
= IDXGIDevice_GetAdapter(dxgi_device
, &adapter
);
215 ok(hr
== S_OK
, "Failed to get adapter, hr %#lx.\n", hr
);
216 IDXGIDevice_Release(dxgi_device
);
217 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
218 ok(hr
== S_OK
, "Failed to get factory, hr %#lx.\n", hr
);
219 IDXGIAdapter_Release(adapter
);
221 dxgi_desc
.BufferDesc
.Width
= RENDER_TARGET_WIDTH
;
222 dxgi_desc
.BufferDesc
.Height
= RENDER_TARGET_HEIGHT
;
223 dxgi_desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
224 dxgi_desc
.BufferDesc
.RefreshRate
.Denominator
= 1;
225 dxgi_desc
.BufferDesc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
226 dxgi_desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
227 dxgi_desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
228 dxgi_desc
.SampleDesc
.Count
= 1;
229 dxgi_desc
.SampleDesc
.Quality
= 0;
230 dxgi_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
231 dxgi_desc
.BufferCount
= 1;
232 dxgi_desc
.OutputWindow
= window
;
233 dxgi_desc
.Windowed
= TRUE
;
234 dxgi_desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
237 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &dxgi_desc
, &swapchain
);
238 ok(hr
== S_OK
, "Failed to create swapchain, hr %#lx.\n", hr
);
239 IDXGIFactory_Release(factory
);
244 static bool get_format_support(ID3D11Device
*device
, enum DXGI_FORMAT format
)
246 D3D11_FEATURE_DATA_FORMAT_SUPPORT2 format_support2
= {.InFormat
= format
};
250 hr
= ID3D11Device_CheckFeatureSupport(device
, D3D11_FEATURE_FORMAT_SUPPORT2
,
251 &format_support2
, sizeof(format_support2
));
252 ok(hr
== S_OK
, "Failed to query format support2, hr %#lx.\n", hr
);
254 if (format_support2
.OutFormatSupport2
& D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD
)
255 ret
|= FORMAT_CAP_UAV_LOAD
;
260 static BOOL
init_test_context(struct d3d11_shader_runner
*runner
)
262 D3D11_FEATURE_DATA_D3D11_OPTIONS2 options2
= {0};
263 D3D11_FEATURE_DATA_D3D11_OPTIONS3 options3
= {0};
264 D3D11_FEATURE_DATA_DOUBLES doubles
= {0};
265 unsigned int rt_width
, rt_height
;
266 D3D11_RASTERIZER_DESC rs_desc
;
270 static const enum DXGI_FORMAT formats
[] =
272 DXGI_FORMAT_R32_FLOAT
,
273 DXGI_FORMAT_R32_UINT
,
274 DXGI_FORMAT_R32_SINT
,
275 DXGI_FORMAT_R32G32B32A32_FLOAT
,
276 DXGI_FORMAT_R32G32B32A32_UINT
,
277 DXGI_FORMAT_R32G32B32A32_SINT
,
278 DXGI_FORMAT_R16G16B16A16_FLOAT
,
279 DXGI_FORMAT_R16G16B16A16_UINT
,
280 DXGI_FORMAT_R16G16B16A16_SINT
,
281 DXGI_FORMAT_R8G8B8A8_UNORM
,
282 DXGI_FORMAT_R8G8B8A8_UINT
,
283 DXGI_FORMAT_R8G8B8A8_SINT
,
284 DXGI_FORMAT_R16_FLOAT
,
285 DXGI_FORMAT_R16_UINT
,
286 DXGI_FORMAT_R16_SINT
,
287 DXGI_FORMAT_R8_UNORM
,
292 memset(runner
, 0, sizeof(*runner
));
294 if (!(runner
->device
= create_device()))
296 skip("Failed to create device.\n");
300 runner
->caps
.runner
= "d3d11.dll";
301 runner
->caps
.minimum_shader_model
= SHADER_MODEL_4_0
;
302 runner
->caps
.maximum_shader_model
= SHADER_MODEL_5_0
;
304 hr
= ID3D11Device_CheckFeatureSupport(runner
->device
, D3D11_FEATURE_DOUBLES
,
305 &doubles
, sizeof(doubles
));
306 ok(hr
== S_OK
, "Failed to check double precision feature support, hr %#lx.\n", hr
);
307 runner
->caps
.shader_caps
[SHADER_CAP_FLOAT64
] = doubles
.DoublePrecisionFloatShaderOps
;
309 hr
= ID3D11Device_CheckFeatureSupport(runner
->device
,
310 D3D11_FEATURE_D3D11_OPTIONS2
, &options2
, sizeof(options2
));
311 ok(hr
== S_OK
, "Failed to check feature options2 support, hr %#lx.\n", hr
);
313 hr
= ID3D11Device_CheckFeatureSupport(runner
->device
,
314 D3D11_FEATURE_D3D11_OPTIONS3
, &options3
, sizeof(options3
));
315 ok(hr
== S_OK
, "Failed to check feature options3 support, hr %#lx.\n", hr
);
317 runner
->caps
.shader_caps
[SHADER_CAP_ROV
] = options2
.ROVsSupported
;
318 runner
->caps
.shader_caps
[SHADER_CAP_RT_VP_ARRAY_INDEX
] = options3
.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer
;
319 for (unsigned int i
= 0; i
< ARRAY_SIZE(formats
); ++i
)
321 runner
->caps
.format_caps
[formats
[i
]] = get_format_support(runner
->device
, formats
[i
]);
324 rt_width
= RENDER_TARGET_WIDTH
;
325 rt_height
= RENDER_TARGET_HEIGHT
;
326 SetRect(&rect
, 0, 0, rt_width
, rt_height
);
327 AdjustWindowRect(&rect
, WS_OVERLAPPEDWINDOW
, FALSE
);
328 runner
->window
= CreateWindowA("static", "d3dcompiler_test", WS_OVERLAPPEDWINDOW
,
329 0, 0, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
, NULL
, NULL
, NULL
, NULL
);
330 runner
->swapchain
= create_swapchain(runner
->device
, runner
->window
);
332 ID3D11Device_GetImmediateContext(runner
->device
, &runner
->immediate_context
);
334 set_viewport(runner
->immediate_context
, 0.0f
, 0.0f
, rt_width
, rt_height
, 0.0f
, 1.0f
);
336 rs_desc
.FillMode
= D3D11_FILL_SOLID
;
337 rs_desc
.CullMode
= D3D11_CULL_NONE
;
338 rs_desc
.FrontCounterClockwise
= FALSE
;
339 rs_desc
.DepthBias
= 0;
340 rs_desc
.DepthBiasClamp
= 0.0f
;
341 rs_desc
.SlopeScaledDepthBias
= 0.0f
;
342 rs_desc
.DepthClipEnable
= TRUE
;
343 rs_desc
.ScissorEnable
= FALSE
;
344 rs_desc
.MultisampleEnable
= FALSE
;
345 rs_desc
.AntialiasedLineEnable
= FALSE
;
346 hr
= ID3D11Device_CreateRasterizerState(runner
->device
, &rs_desc
, &runner
->rasterizer_state
);
347 ok(hr
== S_OK
, "Failed to create rasterizer state.\n");
352 static void destroy_test_context(struct d3d11_shader_runner
*runner
)
356 ID3D11RasterizerState_Release(runner
->rasterizer_state
);
357 ID3D11DeviceContext_Release(runner
->immediate_context
);
358 IDXGISwapChain_Release(runner
->swapchain
);
359 DestroyWindow(runner
->window
);
361 ref
= ID3D11Device_Release(runner
->device
);
362 ok(!ref
, "Device has %lu references left.\n", ref
);
365 static ID3D11Buffer
*create_buffer(ID3D11Device
*device
, unsigned int bind_flags
, unsigned int size
,
366 bool is_raw
, unsigned int stride
, const void *data
)
368 D3D11_SUBRESOURCE_DATA resource_data
;
369 D3D11_BUFFER_DESC buffer_desc
;
370 ID3D11Buffer
*buffer
;
373 buffer_desc
.ByteWidth
= size
;
374 buffer_desc
.Usage
= D3D11_USAGE_DEFAULT
;
375 buffer_desc
.BindFlags
= bind_flags
;
376 buffer_desc
.CPUAccessFlags
= 0;
378 buffer_desc
.MiscFlags
= D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS
;
380 buffer_desc
.MiscFlags
= D3D11_RESOURCE_MISC_BUFFER_STRUCTURED
;
382 buffer_desc
.MiscFlags
= 0;
383 buffer_desc
.StructureByteStride
= stride
;
385 resource_data
.pSysMem
= data
;
386 resource_data
.SysMemPitch
= 0;
387 resource_data
.SysMemSlicePitch
= 0;
389 hr
= ID3D11Device_CreateBuffer(device
, &buffer_desc
, data
? &resource_data
: NULL
, &buffer
);
390 ok(hr
== S_OK
, "Failed to create buffer, hr %#lx.\n", hr
);
394 static bool init_resource_2d(struct d3d11_shader_runner
*runner
, struct d3d11_resource
*resource
,
395 const struct resource_params
*params
)
397 D3D11_SUBRESOURCE_DATA resource_data
[3];
398 ID3D11Device
*device
= runner
->device
;
399 D3D11_TEXTURE2D_DESC desc
= {0};
403 if (params
->desc
.level_count
> ARRAY_SIZE(resource_data
))
404 fatal_error("Level count %u is too high.\n", params
->desc
.level_count
);
406 if (params
->desc
.sample_count
> 1)
408 if (params
->desc
.level_count
> 1)
409 fatal_error("Multisampled texture has multiple levels.\n");
411 if (FAILED(ID3D11Device_CheckMultisampleQualityLevels(device
,
412 params
->desc
.format
, params
->desc
.sample_count
, &quality_levels
)) || !quality_levels
)
414 trace("Format #%x with sample count %u is not supported; skipping.\n",
415 params
->desc
.format
, params
->desc
.sample_count
);
420 desc
.Width
= params
->desc
.width
;
421 desc
.Height
= params
->desc
.height
;
422 desc
.MipLevels
= params
->desc
.level_count
;
423 desc
.ArraySize
= params
->desc
.depth
;
424 desc
.Format
= params
->desc
.format
;
425 desc
.SampleDesc
.Count
= max(params
->desc
.sample_count
, 1);
426 desc
.Usage
= D3D11_USAGE_DEFAULT
;
427 if (params
->desc
.type
== RESOURCE_TYPE_UAV
)
428 desc
.BindFlags
= D3D11_BIND_UNORDERED_ACCESS
;
429 else if (params
->desc
.type
== RESOURCE_TYPE_RENDER_TARGET
)
430 desc
.BindFlags
= D3D11_BIND_RENDER_TARGET
;
431 else if (params
->desc
.type
== RESOURCE_TYPE_DEPTH_STENCIL
)
432 desc
.BindFlags
= D3D11_BIND_DEPTH_STENCIL
;
434 desc
.BindFlags
= D3D11_BIND_SHADER_RESOURCE
;
438 unsigned int buffer_offset
= 0;
440 if (params
->desc
.sample_count
> 1)
441 fatal_error("Cannot upload data to a multisampled texture.\n");
443 for (unsigned int level
= 0; level
< params
->desc
.level_count
; ++level
)
445 unsigned int level_width
= get_level_dimension(params
->desc
.width
, level
);
446 unsigned int level_height
= get_level_dimension(params
->desc
.height
, level
);
448 resource_data
[level
].pSysMem
= ¶ms
->data
[buffer_offset
];
449 resource_data
[level
].SysMemPitch
= level_width
* params
->desc
.texel_size
;
450 resource_data
[level
].SysMemSlicePitch
= level_height
* resource_data
[level
].SysMemPitch
;
451 buffer_offset
+= resource_data
[level
].SysMemSlicePitch
;
453 hr
= ID3D11Device_CreateTexture2D(device
, &desc
, resource_data
, &resource
->texture
);
457 hr
= ID3D11Device_CreateTexture2D(device
, &desc
, NULL
, &resource
->texture
);
459 ok(hr
== S_OK
, "Failed to create texture, hr %#lx.\n", hr
);
461 resource
->resource
= (ID3D11Resource
*)resource
->texture
;
462 if (params
->desc
.type
== RESOURCE_TYPE_UAV
)
463 hr
= ID3D11Device_CreateUnorderedAccessView(device
, resource
->resource
, NULL
, &resource
->uav
);
464 else if (params
->desc
.type
== RESOURCE_TYPE_RENDER_TARGET
)
465 hr
= ID3D11Device_CreateRenderTargetView(device
, resource
->resource
, NULL
, &resource
->rtv
);
466 else if (params
->desc
.type
== RESOURCE_TYPE_DEPTH_STENCIL
)
467 hr
= ID3D11Device_CreateDepthStencilView(device
, resource
->resource
, NULL
, &resource
->dsv
);
469 hr
= ID3D11Device_CreateShaderResourceView(device
, resource
->resource
, NULL
, &resource
->srv
);
470 ok(hr
== S_OK
, "Failed to create view, hr %#lx.\n", hr
);
475 static void init_resource_srv_buffer(struct d3d11_shader_runner
*runner
, struct d3d11_resource
*resource
,
476 const struct resource_params
*params
)
478 D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc
;
479 ID3D11Device
*device
= runner
->device
;
482 resource
->buffer
= create_buffer(device
, D3D11_BIND_SHADER_RESOURCE
, params
->data_size
, params
->is_raw
,
483 params
->stride
, params
->data
);
484 resource
->resource
= (ID3D11Resource
*)resource
->buffer
;
486 srv_desc
.Format
= params
->desc
.format
;
489 srv_desc
.ViewDimension
= D3D11_SRV_DIMENSION_BUFFEREX
;
490 srv_desc
.BufferEx
.FirstElement
= 0;
491 srv_desc
.BufferEx
.NumElements
= params
->data_size
/ params
->desc
.texel_size
;
492 srv_desc
.BufferEx
.Flags
= D3D11_BUFFEREX_SRV_FLAG_RAW
;
496 srv_desc
.ViewDimension
= D3D11_SRV_DIMENSION_BUFFER
;
497 srv_desc
.Buffer
.FirstElement
= 0;
498 srv_desc
.Buffer
.NumElements
= params
->data_size
/ params
->desc
.texel_size
;
500 hr
= ID3D11Device_CreateShaderResourceView(device
, resource
->resource
, &srv_desc
, &resource
->srv
);
501 ok(hr
== S_OK
, "Failed to create view, hr %#lx.\n", hr
);
504 static void init_resource_uav_buffer(struct d3d11_shader_runner
*runner
, struct d3d11_resource
*resource
,
505 const struct resource_params
*params
)
507 D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc
;
508 ID3D11Device
*device
= runner
->device
;
511 resource
->buffer
= create_buffer(device
, D3D11_BIND_UNORDERED_ACCESS
, params
->data_size
, params
->is_raw
,
512 params
->stride
, params
->data
);
513 resource
->resource
= (ID3D11Resource
*)resource
->buffer
;
514 resource
->is_uav_counter
= params
->is_uav_counter
;
516 uav_desc
.Format
= params
->desc
.format
;
517 uav_desc
.ViewDimension
= D3D11_UAV_DIMENSION_BUFFER
;
518 uav_desc
.Buffer
.FirstElement
= 0;
519 uav_desc
.Buffer
.NumElements
= params
->data_size
/ params
->desc
.texel_size
;
521 uav_desc
.Buffer
.Flags
= D3D11_BUFFER_UAV_FLAG_RAW
;
522 else if (params
->is_uav_counter
)
523 uav_desc
.Buffer
.Flags
= D3D11_BUFFER_UAV_FLAG_COUNTER
;
525 uav_desc
.Buffer
.Flags
= 0;
526 hr
= ID3D11Device_CreateUnorderedAccessView(device
, resource
->resource
, &uav_desc
, &resource
->uav
);
527 ok(hr
== S_OK
, "Failed to create view, hr %#lx.\n", hr
);
530 static struct resource
*d3d11_runner_create_resource(struct shader_runner
*r
, const struct resource_params
*params
)
532 struct d3d11_shader_runner
*runner
= d3d11_shader_runner(r
);
533 ID3D11Device
*device
= runner
->device
;
534 struct d3d11_resource
*resource
;
536 resource
= calloc(1, sizeof(*resource
));
537 init_resource(&resource
->r
, params
);
539 switch (params
->desc
.type
)
541 case RESOURCE_TYPE_RENDER_TARGET
:
542 case RESOURCE_TYPE_DEPTH_STENCIL
:
543 case RESOURCE_TYPE_TEXTURE
:
544 if (params
->desc
.dimension
== RESOURCE_DIMENSION_BUFFER
)
545 init_resource_srv_buffer(runner
, resource
, params
);
546 else if (!init_resource_2d(runner
, resource
, params
))
550 case RESOURCE_TYPE_UAV
:
551 if (params
->desc
.dimension
== RESOURCE_DIMENSION_BUFFER
)
552 init_resource_uav_buffer(runner
, resource
, params
);
553 else if (!init_resource_2d(runner
, resource
, params
))
557 case RESOURCE_TYPE_VERTEX_BUFFER
:
558 resource
->buffer
= create_buffer(device
, D3D11_BIND_VERTEX_BUFFER
, params
->data_size
, params
->is_raw
,
559 params
->stride
, params
->data
);
560 resource
->resource
= (ID3D11Resource
*)resource
->buffer
;
567 static void d3d11_runner_destroy_resource(struct shader_runner
*r
, struct resource
*res
)
569 struct d3d11_resource
*resource
= d3d11_resource(res
);
571 ID3D11Resource_Release(resource
->resource
);
573 ID3D11RenderTargetView_Release(resource
->rtv
);
575 ID3D11DepthStencilView_Release(resource
->dsv
);
577 ID3D11ShaderResourceView_Release(resource
->srv
);
579 ID3D11UnorderedAccessView_Release(resource
->uav
);
583 static ID3D11SamplerState
*create_sampler(ID3D11Device
*device
, const struct sampler
*sampler
)
585 ID3D11SamplerState
*d3d11_sampler
;
586 D3D11_SAMPLER_DESC desc
= {0};
589 /* Members of D3D11_FILTER are compatible with D3D12_FILTER. */
590 desc
.Filter
= (D3D11_FILTER
)sampler
->filter
;
591 /* Members of D3D11_TEXTURE_ADDRESS_MODE are compatible with D3D12_TEXTURE_ADDRESS_MODE. */
592 desc
.AddressU
= (D3D11_TEXTURE_ADDRESS_MODE
)sampler
->u_address
;
593 desc
.AddressV
= (D3D11_TEXTURE_ADDRESS_MODE
)sampler
->v_address
;
594 desc
.AddressW
= (D3D11_TEXTURE_ADDRESS_MODE
)sampler
->w_address
;
595 desc
.ComparisonFunc
= sampler
->func
;
596 desc
.MaxLOD
= D3D11_FLOAT32_MAX
;
598 hr
= ID3D11Device_CreateSamplerState(device
, &desc
, &d3d11_sampler
);
599 ok(hr
== S_OK
, "Failed to create sampler state, hr %#lx.\n", hr
);
600 return d3d11_sampler
;
603 static bool d3d11_runner_dispatch(struct shader_runner
*r
, unsigned int x
, unsigned int y
, unsigned int z
)
605 struct d3d11_shader_runner
*runner
= d3d11_shader_runner(r
);
606 ID3D11DeviceContext
*context
= runner
->immediate_context
;
607 ID3D11Device
*device
= runner
->device
;
608 ID3D11ComputeShader
*cs
;
613 if (!(cs_code
= compile_hlsl(&runner
->r
, SHADER_TYPE_CS
)))
616 hr
= ID3D11Device_CreateComputeShader(device
, ID3D10Blob_GetBufferPointer(cs_code
),
617 ID3D10Blob_GetBufferSize(cs_code
), NULL
, &cs
);
618 ok(hr
== S_OK
, "Failed to create compute shader, hr %#lx.\n", hr
);
620 if (runner
->r
.uniform_count
)
624 cb
= create_buffer(device
, D3D11_BIND_CONSTANT_BUFFER
,
625 runner
->r
.uniform_count
* sizeof(*runner
->r
.uniforms
), false, 0, runner
->r
.uniforms
);
626 ID3D11DeviceContext_CSSetConstantBuffers(context
, 0, 1, &cb
);
627 ID3D11Buffer_Release(cb
);
630 for (i
= 0; i
< runner
->r
.resource_count
; ++i
)
632 struct d3d11_resource
*resource
= d3d11_resource(runner
->r
.resources
[i
]);
634 switch (resource
->r
.desc
.type
)
636 case RESOURCE_TYPE_TEXTURE
:
637 ID3D11DeviceContext_CSSetShaderResources(context
, resource
->r
.desc
.slot
, 1, &resource
->srv
);
640 case RESOURCE_TYPE_UAV
:
641 ID3D11DeviceContext_CSSetUnorderedAccessViews(context
, resource
->r
.desc
.slot
, 1, &resource
->uav
, NULL
);
644 case RESOURCE_TYPE_RENDER_TARGET
:
645 case RESOURCE_TYPE_DEPTH_STENCIL
:
646 case RESOURCE_TYPE_VERTEX_BUFFER
:
651 for (i
= 0; i
< runner
->r
.sampler_count
; ++i
)
653 struct sampler
*sampler
= &runner
->r
.samplers
[i
];
654 ID3D11SamplerState
*d3d11_sampler
;
656 d3d11_sampler
= create_sampler(device
, sampler
);
657 ID3D11DeviceContext_CSSetSamplers(context
, sampler
->slot
, 1, &d3d11_sampler
);
658 ID3D11SamplerState_Release(d3d11_sampler
);
661 ID3D11DeviceContext_CSSetShader(context
, cs
, NULL
, 0);
662 ID3D11DeviceContext_Dispatch(context
, x
, y
, z
);
664 ID3D11ComputeShader_Release(cs
);
669 static void d3d11_runner_clear(struct shader_runner
*r
, struct resource
*res
, const struct vec4
*clear_value
)
671 struct d3d11_shader_runner
*runner
= d3d11_shader_runner(r
);
672 ID3D11DeviceContext
*context
= runner
->immediate_context
;
673 struct d3d11_resource
*resource
= d3d11_resource(res
);
675 switch (resource
->r
.desc
.type
)
677 case RESOURCE_TYPE_RENDER_TARGET
:
678 ID3D11DeviceContext_ClearRenderTargetView(context
, resource
->rtv
, (const float *)clear_value
);
681 case RESOURCE_TYPE_DEPTH_STENCIL
:
682 ID3D11DeviceContext_ClearDepthStencilView(context
, resource
->dsv
, D3D11_CLEAR_DEPTH
, clear_value
->x
, 0);
686 fatal_error("Clears are not implemented for resource type %u.\n", resource
->r
.desc
.type
);
690 static bool d3d11_runner_draw(struct shader_runner
*r
,
691 D3D_PRIMITIVE_TOPOLOGY primitive_topology
, unsigned int vertex_count
, unsigned int instance_count
)
693 ID3D10Blob
*vs_code
, *ps_code
, *hs_code
= NULL
, *ds_code
= NULL
, *gs_code
= NULL
;
694 ID3D11UnorderedAccessView
*uavs
[D3D11_PS_CS_UAV_REGISTER_COUNT
] = {0};
695 ID3D11RenderTargetView
*rtvs
[D3D11_PS_CS_UAV_REGISTER_COUNT
] = {0};
696 struct d3d11_shader_runner
*runner
= d3d11_shader_runner(r
);
697 ID3D11DeviceContext
*context
= runner
->immediate_context
;
698 unsigned int fb_width
, fb_height
, rtv_count
= 0;
699 unsigned int min_uav_slot
= ARRAY_SIZE(uavs
);
700 ID3D11DepthStencilState
*ds_state
= NULL
;
701 D3D11_DEPTH_STENCIL_DESC ds_desc
= {0};
702 ID3D11Device
*device
= runner
->device
;
703 ID3D11DepthStencilView
*dsv
= NULL
;
704 ID3D11GeometryShader
*gs
;
705 ID3D11Buffer
*cb
= NULL
;
706 ID3D11VertexShader
*vs
;
707 ID3D11DomainShader
*ds
;
708 ID3D11PixelShader
*ps
;
709 ID3D11HullShader
*hs
;
714 vs_code
= compile_hlsl(&runner
->r
, SHADER_TYPE_VS
);
715 ps_code
= compile_hlsl(&runner
->r
, SHADER_TYPE_PS
);
716 succeeded
= vs_code
&& ps_code
;
718 if (runner
->r
.shader_source
[SHADER_TYPE_HS
])
720 hs_code
= compile_hlsl(&runner
->r
, SHADER_TYPE_HS
);
721 succeeded
= succeeded
&& hs_code
;
723 if (runner
->r
.shader_source
[SHADER_TYPE_DS
])
725 ds_code
= compile_hlsl(&runner
->r
, SHADER_TYPE_DS
);
726 succeeded
= succeeded
&& ds_code
;
728 if (runner
->r
.shader_source
[SHADER_TYPE_GS
])
730 gs_code
= compile_hlsl(&runner
->r
, SHADER_TYPE_GS
);
731 succeeded
= succeeded
&& gs_code
;
737 ID3D10Blob_Release(ps_code
);
739 ID3D10Blob_Release(vs_code
);
741 ID3D10Blob_Release(hs_code
);
743 ID3D10Blob_Release(ds_code
);
745 ID3D10Blob_Release(gs_code
);
749 hr
= ID3D11Device_CreateVertexShader(device
, ID3D10Blob_GetBufferPointer(vs_code
),
750 ID3D10Blob_GetBufferSize(vs_code
), NULL
, &vs
);
751 ok(hr
== S_OK
, "Failed to create vertex shader, hr %#lx.\n", hr
);
753 hr
= ID3D11Device_CreatePixelShader(device
, ID3D10Blob_GetBufferPointer(ps_code
),
754 ID3D10Blob_GetBufferSize(ps_code
), NULL
, &ps
);
755 ok(hr
== S_OK
, "Failed to create pixel shader, hr %#lx.\n", hr
);
759 hr
= ID3D11Device_CreateHullShader(device
, ID3D10Blob_GetBufferPointer(hs_code
),
760 ID3D10Blob_GetBufferSize(hs_code
), NULL
, &hs
);
761 ok(hr
== S_OK
, "Failed to create hull shader, hr %#lx.\n", hr
);
765 hr
= ID3D11Device_CreateDomainShader(device
, ID3D10Blob_GetBufferPointer(ds_code
),
766 ID3D10Blob_GetBufferSize(ds_code
), NULL
, &ds
);
767 ok(hr
== S_OK
, "Failed to create domain shader, hr %#lx.\n", hr
);
771 hr
= ID3D11Device_CreateGeometryShader(device
, ID3D10Blob_GetBufferPointer(gs_code
),
772 ID3D10Blob_GetBufferSize(gs_code
), NULL
, &gs
);
773 ok(hr
== S_OK
, "Failed to create geometry shader, hr %#lx.\n", hr
);
776 ID3D10Blob_Release(ps_code
);
778 ID3D10Blob_Release(hs_code
);
780 ID3D10Blob_Release(ds_code
);
782 ID3D10Blob_Release(gs_code
);
784 if (runner
->r
.uniform_count
)
786 cb
= create_buffer(device
, D3D11_BIND_CONSTANT_BUFFER
,
787 runner
->r
.uniform_count
* sizeof(*runner
->r
.uniforms
), false, 0, runner
->r
.uniforms
);
788 ID3D11DeviceContext_VSSetConstantBuffers(context
, 0, 1, &cb
);
789 ID3D11DeviceContext_PSSetConstantBuffers(context
, 0, 1, &cb
);
791 ID3D11DeviceContext_HSSetConstantBuffers(context
, 0, 1, &cb
);
793 ID3D11DeviceContext_DSSetConstantBuffers(context
, 0, 1, &cb
);
795 ID3D11DeviceContext_GSSetConstantBuffers(context
, 0, 1, &cb
);
800 for (i
= 0; i
< runner
->r
.resource_count
; ++i
)
802 struct d3d11_resource
*resource
= d3d11_resource(runner
->r
.resources
[i
]);
803 unsigned int stride
= get_vb_stride(&runner
->r
, resource
->r
.desc
.slot
);
804 unsigned int offset
= 0;
806 switch (resource
->r
.desc
.type
)
808 case RESOURCE_TYPE_RENDER_TARGET
:
809 rtvs
[resource
->r
.desc
.slot
] = resource
->rtv
;
810 rtv_count
= max(rtv_count
, resource
->r
.desc
.slot
+ 1);
811 if (resource
->r
.desc
.width
< fb_width
)
812 fb_width
= resource
->r
.desc
.width
;
813 if (resource
->r
.desc
.height
< fb_height
)
814 fb_height
= resource
->r
.desc
.height
;
817 case RESOURCE_TYPE_DEPTH_STENCIL
:
819 ds_desc
.DepthEnable
= TRUE
;
820 ds_desc
.DepthWriteMask
= D3D11_DEPTH_WRITE_MASK_ALL
;
821 ds_desc
.DepthFunc
= runner
->r
.depth_func
;
822 hr
= ID3D11Device_CreateDepthStencilState(device
, &ds_desc
, &ds_state
);
823 ok(hr
== S_OK
, "Failed to create depth/stencil state, hr %#lx.\n", hr
);
824 ID3D11DeviceContext_OMSetDepthStencilState(context
, ds_state
, 0);
825 if (resource
->r
.desc
.width
< fb_width
)
826 fb_width
= resource
->r
.desc
.width
;
827 if (resource
->r
.desc
.height
< fb_height
)
828 fb_height
= resource
->r
.desc
.height
;
831 case RESOURCE_TYPE_TEXTURE
:
832 ID3D11DeviceContext_PSSetShaderResources(context
, resource
->r
.desc
.slot
, 1, &resource
->srv
);
835 case RESOURCE_TYPE_UAV
:
836 uavs
[resource
->r
.desc
.slot
] = resource
->uav
;
837 min_uav_slot
= min(min_uav_slot
, resource
->r
.desc
.slot
);
840 case RESOURCE_TYPE_VERTEX_BUFFER
:
841 ID3D11DeviceContext_IASetVertexBuffers(context
, resource
->r
.desc
.slot
, 1,
842 (ID3D11Buffer
**)&resource
->resource
, &stride
, &offset
);
847 ID3D11DeviceContext_OMSetRenderTargetsAndUnorderedAccessViews(context
, rtv_count
, rtvs
, dsv
,
848 min_uav_slot
, ARRAY_SIZE(uavs
) - min_uav_slot
, &uavs
[min_uav_slot
], NULL
);
850 for (i
= 0; i
< runner
->r
.sampler_count
; ++i
)
852 struct sampler
*sampler
= &runner
->r
.samplers
[i
];
853 ID3D11SamplerState
*d3d11_sampler
;
855 d3d11_sampler
= create_sampler(device
, sampler
);
856 ID3D11DeviceContext_PSSetSamplers(context
, sampler
->slot
, 1, &d3d11_sampler
);
857 ID3D11SamplerState_Release(d3d11_sampler
);
860 if (runner
->r
.input_element_count
)
862 D3D11_INPUT_ELEMENT_DESC
*descs
;
863 ID3D11InputLayout
*input_layout
;
865 descs
= calloc(runner
->r
.input_element_count
, sizeof(*descs
));
866 for (i
= 0; i
< runner
->r
.input_element_count
; ++i
)
868 const struct input_element
*element
= &runner
->r
.input_elements
[i
];
869 D3D11_INPUT_ELEMENT_DESC
*desc
= &descs
[i
];
871 desc
->SemanticName
= element
->name
;
872 desc
->SemanticIndex
= element
->index
;
873 desc
->Format
= element
->format
;
874 desc
->InputSlot
= element
->slot
;
875 desc
->AlignedByteOffset
= D3D11_APPEND_ALIGNED_ELEMENT
;
876 desc
->InputSlotClass
= D3D11_INPUT_PER_VERTEX_DATA
;
879 hr
= ID3D11Device_CreateInputLayout(device
, descs
, runner
->r
.input_element_count
,
880 ID3D10Blob_GetBufferPointer(vs_code
), ID3D10Blob_GetBufferSize(vs_code
), &input_layout
);
881 ok(hr
== S_OK
, "Failed to create input layout, hr %#lx.\n", hr
);
882 ID3D11DeviceContext_IASetInputLayout(context
, input_layout
);
883 ID3D11InputLayout_Release(input_layout
);
886 ID3D10Blob_Release(vs_code
);
889 ID3D11DeviceContext_OMSetBlendState(context
, NULL
, NULL
, r
->sample_mask
);
890 ID3D11DeviceContext_IASetPrimitiveTopology(context
, primitive_topology
);
891 ID3D11DeviceContext_VSSetShader(context
, vs
, NULL
, 0);
892 ID3D11DeviceContext_PSSetShader(context
, ps
, NULL
, 0);
894 ID3D11DeviceContext_HSSetShader(context
, hs
, NULL
, 0);
896 ID3D11DeviceContext_DSSetShader(context
, ds
, NULL
, 0);
898 ID3D11DeviceContext_GSSetShader(context
, gs
, NULL
, 0);
899 ID3D11DeviceContext_RSSetState(context
, runner
->rasterizer_state
);
900 set_viewport(context
, 0.0f
, 0.0f
, fb_width
, fb_height
, 0.0f
, 1.0f
);
902 ID3D11DeviceContext_DrawInstanced(context
, vertex_count
, instance_count
, 0, 0);
904 ID3D11PixelShader_Release(ps
);
905 ID3D11VertexShader_Release(vs
);
907 ID3D11HullShader_Release(hs
);
909 ID3D11DomainShader_Release(ds
);
911 ID3D11GeometryShader_Release(gs
);
913 ID3D11Buffer_Release(cb
);
915 ID3D11DepthStencilState_Release(ds_state
);
920 static bool d3d11_runner_copy(struct shader_runner
*r
, struct resource
*src
, struct resource
*dst
)
922 struct d3d11_shader_runner
*runner
= d3d11_shader_runner(r
);
923 struct d3d11_resource
*s
= d3d11_resource(src
);
924 struct d3d11_resource
*d
= d3d11_resource(dst
);
926 ID3D11DeviceContext_CopyResource(runner
->immediate_context
, d
->resource
, s
->resource
);
931 struct d3d11_resource_readback
933 struct resource_readback rb
;
934 ID3D11Resource
*resource
;
935 unsigned int sub_resource_idx
;
938 static struct resource_readback
*d3d11_runner_get_resource_readback(struct shader_runner
*r
,
939 struct resource
*res
, unsigned int sub_resource_idx
)
941 struct d3d11_shader_runner
*runner
= d3d11_shader_runner(r
);
942 struct d3d11_resource_readback
*rb
= malloc(sizeof(*rb
));
943 ID3D11Resource
*resolved_resource
= NULL
, *src_resource
;
944 struct d3d11_resource
*resource
= d3d11_resource(res
);
945 D3D11_TEXTURE2D_DESC texture_desc
;
946 D3D11_MAPPED_SUBRESOURCE map_desc
;
947 D3D11_BUFFER_DESC buffer_desc
;
951 src_resource
= resource
->resource
;
952 switch (resource
->r
.desc
.type
)
954 case RESOURCE_TYPE_RENDER_TARGET
:
955 case RESOURCE_TYPE_DEPTH_STENCIL
:
956 case RESOURCE_TYPE_UAV
:
957 if (resource
->r
.desc
.dimension
== RESOURCE_DIMENSION_BUFFER
)
959 ID3D11Buffer_GetDesc(resource
->buffer
, &buffer_desc
);
960 buffer_desc
.Usage
= D3D11_USAGE_STAGING
;
961 buffer_desc
.BindFlags
= 0;
962 buffer_desc
.CPUAccessFlags
= D3D11_CPU_ACCESS_READ
;
963 buffer_desc
.MiscFlags
= 0;
964 hr
= ID3D11Device_CreateBuffer(runner
->device
, &buffer_desc
, NULL
, (ID3D11Buffer
**)&rb
->resource
);
965 ok(hr
== S_OK
, "Failed to create buffer, hr %#lx.\n", hr
);
969 ID3D11Texture2D_GetDesc(resource
->texture
, &texture_desc
);
970 is_ms
= texture_desc
.SampleDesc
.Count
> 1;
971 texture_desc
.SampleDesc
.Count
= 1;
972 texture_desc
.SampleDesc
.Quality
= 0;
973 texture_desc
.Usage
= D3D11_USAGE_STAGING
;
974 texture_desc
.BindFlags
= 0;
975 texture_desc
.CPUAccessFlags
= D3D11_CPU_ACCESS_READ
;
976 texture_desc
.MiscFlags
= 0;
977 hr
= ID3D11Device_CreateTexture2D(runner
->device
, &texture_desc
, NULL
, (ID3D11Texture2D
**)&rb
->resource
);
978 ok(hr
== S_OK
, "Failed to create texture, hr %#lx.\n", hr
);
981 texture_desc
.Usage
= D3D11_USAGE_DEFAULT
;
982 hr
= ID3D11Device_CreateTexture2D(runner
->device
, &texture_desc
, NULL
,
983 (ID3D11Texture2D
**)&resolved_resource
);
984 ok(hr
== S_OK
, "Failed to create multisampled texture, hr %#lx.\n", hr
);
985 ID3D11DeviceContext_ResolveSubresource(runner
->immediate_context
, resolved_resource
, 0,
986 resource
->resource
, 0, texture_desc
.Format
);
987 src_resource
= resolved_resource
;
992 case RESOURCE_TYPE_VERTEX_BUFFER
:
993 case RESOURCE_TYPE_TEXTURE
:
997 if (resource
->is_uav_counter
)
998 ID3D11DeviceContext_CopyStructureCount(runner
->immediate_context
, (ID3D11Buffer
*)rb
->resource
, 0, resource
->uav
);
1000 ID3D11DeviceContext_CopyResource(runner
->immediate_context
, rb
->resource
, src_resource
);
1001 hr
= ID3D11DeviceContext_Map(runner
->immediate_context
, rb
->resource
,
1002 sub_resource_idx
, D3D11_MAP_READ
, 0, &map_desc
);
1003 ok(hr
== S_OK
, "Failed to map texture, hr %#lx.\n", hr
);
1005 if (resolved_resource
)
1006 ID3D11Resource_Release(resolved_resource
);
1008 rb
->rb
.data
= map_desc
.pData
;
1009 rb
->rb
.row_pitch
= map_desc
.RowPitch
;
1010 rb
->rb
.width
= resource
->r
.desc
.width
;
1011 rb
->rb
.height
= resource
->r
.desc
.height
;
1013 rb
->sub_resource_idx
= sub_resource_idx
;
1018 static void d3d11_runner_release_readback(struct shader_runner
*r
, struct resource_readback
*rb
)
1020 struct d3d11_resource_readback
*d3d11_rb
= CONTAINING_RECORD(rb
, struct d3d11_resource_readback
, rb
);
1021 struct d3d11_shader_runner
*runner
= d3d11_shader_runner(r
);
1023 ID3D11DeviceContext_Unmap(runner
->immediate_context
, d3d11_rb
->resource
, d3d11_rb
->sub_resource_idx
);
1024 ID3D11Resource_Release(d3d11_rb
->resource
);
1028 static const struct shader_runner_ops d3d11_runner_ops
=
1030 .create_resource
= d3d11_runner_create_resource
,
1031 .destroy_resource
= d3d11_runner_destroy_resource
,
1032 .dispatch
= d3d11_runner_dispatch
,
1033 .clear
= d3d11_runner_clear
,
1034 .draw
= d3d11_runner_draw
,
1035 .copy
= d3d11_runner_copy
,
1036 .get_resource_readback
= d3d11_runner_get_resource_readback
,
1037 .release_readback
= d3d11_runner_release_readback
,
1040 void run_shader_tests_d3d11(void)
1042 struct d3d11_shader_runner runner
;
1043 HMODULE dxgi_module
, d3d11_module
;
1045 d3d11_module
= LoadLibraryA("d3d11.dll");
1046 dxgi_module
= LoadLibraryA("dxgi.dll");
1047 if (d3d11_module
&& dxgi_module
)
1049 pCreateDXGIFactory1
= (void *)GetProcAddress(dxgi_module
, "CreateDXGIFactory1");
1050 pD3D11CreateDevice
= (void *)GetProcAddress(d3d11_module
, "D3D11CreateDevice");
1052 init_adapter_info();
1053 if (init_test_context(&runner
))
1055 run_shader_tests(&runner
.r
, &runner
.caps
, &d3d11_runner_ops
, NULL
);
1056 destroy_test_context(&runner
);
1059 FreeLibrary(d3d11_module
);
1060 FreeLibrary(dxgi_module
);