wined3d: Pass a wined3d_device_context to wined3d_cs_emit_blt_sub_resource().
[wine/zf.git] / dlls / d3dcompiler_43 / tests / hlsl_d3d11.c
blob53dbd3e2df7e87e0217542c071e361e26fc5df68
1 /*
2 * Copyright (C) 2020 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
19 #include <limits.h>
20 #include <math.h>
22 #define COBJMACROS
23 #include "d3dcompiler.h"
24 #include "d3d11.h"
25 #include "wine/test.h"
27 static pD3DCompile ppD3DCompile;
28 static HRESULT (WINAPI *pD3DReflect)(const void *data, SIZE_T size, REFIID iid, void **out);
30 static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type,
31 HMODULE swrast, UINT flags, const D3D_FEATURE_LEVEL *feature_levels, UINT levels,
32 UINT sdk_version, ID3D11Device **device_out, D3D_FEATURE_LEVEL *obtained_feature_level,
33 ID3D11DeviceContext **immediate_context);
35 struct vec2
37 float x, y;
40 struct vec4
42 float x, y, z, w;
45 #define compile_shader(a, b) compile_shader_(__LINE__, a, b, 0)
46 #define compile_shader_flags(a, b, c) compile_shader_(__LINE__, a, b, c)
47 static ID3D10Blob *compile_shader_(unsigned int line, const char *source, const char *target, UINT flags)
49 ID3D10Blob *blob = NULL, *errors = NULL;
50 HRESULT hr;
52 hr = ppD3DCompile(source, strlen(source), NULL, NULL, NULL, "main", target, flags, 0, &blob, &errors);
53 ok_(__FILE__, line)(hr == S_OK, "Failed to compile shader, hr %#x.\n", hr);
54 if (errors)
56 if (winetest_debug > 1)
57 trace_(__FILE__, line)("%s\n", (char *)ID3D10Blob_GetBufferPointer(errors));
58 ID3D10Blob_Release(errors);
60 return blob;
63 static BOOL compare_float(float f, float g, unsigned int ulps)
65 int x = *(int *)&f;
66 int y = *(int *)&g;
68 if (x < 0)
69 x = INT_MIN - x;
70 if (y < 0)
71 y = INT_MIN - y;
73 if (abs(x - y) > ulps)
74 return FALSE;
76 return TRUE;
79 static BOOL compare_vec4(const struct vec4 *vec, float x, float y, float z, float w, unsigned int ulps)
81 return compare_float(vec->x, x, ulps)
82 && compare_float(vec->y, y, ulps)
83 && compare_float(vec->z, z, ulps)
84 && compare_float(vec->w, w, ulps);
87 struct test_context
89 ID3D11Device *device;
90 HWND window;
91 IDXGISwapChain *swapchain;
92 ID3D11Texture2D *rt;
93 ID3D11RenderTargetView *rtv;
94 ID3D11DeviceContext *immediate_context;
96 ID3D11InputLayout *input_layout;
97 ID3D11VertexShader *vs;
98 ID3D11Buffer *vb;
101 static ID3D11Device *create_device(void)
103 static const D3D_FEATURE_LEVEL feature_level[] =
105 D3D_FEATURE_LEVEL_11_0,
106 D3D_FEATURE_LEVEL_10_1,
107 D3D_FEATURE_LEVEL_10_0,
109 ID3D11Device *device;
111 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
112 feature_level, ARRAY_SIZE(feature_level), D3D11_SDK_VERSION, &device, NULL, NULL)))
113 return device;
114 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0,
115 feature_level, ARRAY_SIZE(feature_level), D3D11_SDK_VERSION, &device, NULL, NULL)))
116 return device;
117 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0,
118 feature_level, ARRAY_SIZE(feature_level), D3D11_SDK_VERSION, &device, NULL, NULL)))
119 return device;
121 return NULL;
124 static IDXGISwapChain *create_swapchain(ID3D11Device *device, HWND window)
126 DXGI_SWAP_CHAIN_DESC dxgi_desc;
127 IDXGISwapChain *swapchain;
128 IDXGIDevice *dxgi_device;
129 IDXGIAdapter *adapter;
130 IDXGIFactory *factory;
131 HRESULT hr;
133 hr = ID3D11Device_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgi_device);
134 ok(SUCCEEDED(hr), "Failed to get DXGI device, hr %#x.\n", hr);
135 hr = IDXGIDevice_GetAdapter(dxgi_device, &adapter);
136 ok(SUCCEEDED(hr), "Failed to get adapter, hr %#x.\n", hr);
137 IDXGIDevice_Release(dxgi_device);
138 hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
139 ok(SUCCEEDED(hr), "Failed to get factory, hr %#x.\n", hr);
140 IDXGIAdapter_Release(adapter);
142 dxgi_desc.BufferDesc.Width = 640;
143 dxgi_desc.BufferDesc.Height = 480;
144 dxgi_desc.BufferDesc.RefreshRate.Numerator = 60;
145 dxgi_desc.BufferDesc.RefreshRate.Denominator = 1;
146 dxgi_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
147 dxgi_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
148 dxgi_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
149 dxgi_desc.SampleDesc.Count = 1;
150 dxgi_desc.SampleDesc.Quality = 0;
151 dxgi_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
152 dxgi_desc.BufferCount = 1;
153 dxgi_desc.OutputWindow = window;
154 dxgi_desc.Windowed = TRUE;
155 dxgi_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
156 dxgi_desc.Flags = 0;
158 hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &dxgi_desc, &swapchain);
159 ok(SUCCEEDED(hr), "Failed to create swapchain, hr %#x.\n", hr);
160 IDXGIFactory_Release(factory);
162 return swapchain;
165 #define init_test_context(a) init_test_context_(__LINE__, a)
166 static BOOL init_test_context_(unsigned int line, struct test_context *context)
168 const D3D11_TEXTURE2D_DESC texture_desc =
170 .Width = 640,
171 .Height = 480,
172 .MipLevels = 1,
173 .ArraySize = 1,
174 .Format = DXGI_FORMAT_R32G32B32A32_FLOAT,
175 .SampleDesc.Count = 1,
176 .Usage = D3D11_USAGE_DEFAULT,
177 .BindFlags = D3D11_BIND_RENDER_TARGET,
179 unsigned int rt_width, rt_height;
180 D3D11_VIEWPORT vp;
181 HRESULT hr;
182 RECT rect;
184 memset(context, 0, sizeof(*context));
186 if (!(context->device = create_device()))
188 skip_(__FILE__, line)("Failed to create device.\n");
189 return FALSE;
192 rt_width = 640;
193 rt_height = 480;
194 SetRect(&rect, 0, 0, rt_width, rt_height);
195 AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
196 context->window = CreateWindowA("static", "d3dcompiler_test", WS_OVERLAPPEDWINDOW,
197 0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, NULL, NULL);
198 context->swapchain = create_swapchain(context->device, context->window);
200 hr = ID3D11Device_CreateTexture2D(context->device, &texture_desc, NULL, &context->rt);
201 ok_(__FILE__, line)(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
203 hr = ID3D11Device_CreateRenderTargetView(context->device, (ID3D11Resource *)context->rt, NULL, &context->rtv);
204 ok_(__FILE__, line)(hr == S_OK, "Failed to create rendertarget view, hr %#x.\n", hr);
206 ID3D11Device_GetImmediateContext(context->device, &context->immediate_context);
208 ID3D11DeviceContext_OMSetRenderTargets(context->immediate_context, 1, &context->rtv, NULL);
210 vp.TopLeftX = 0.0f;
211 vp.TopLeftY = 0.0f;
212 vp.Width = rt_width;
213 vp.Height = rt_height;
214 vp.MinDepth = 0.0f;
215 vp.MaxDepth = 1.0f;
216 ID3D11DeviceContext_RSSetViewports(context->immediate_context, 1, &vp);
218 return TRUE;
221 #define release_test_context(context) release_test_context_(__LINE__, context)
222 static void release_test_context_(unsigned int line, struct test_context *context)
224 ULONG ref;
226 if (context->input_layout)
227 ID3D11InputLayout_Release(context->input_layout);
228 if (context->vs)
229 ID3D11VertexShader_Release(context->vs);
230 if (context->vb)
231 ID3D11Buffer_Release(context->vb);
233 ID3D11DeviceContext_Release(context->immediate_context);
234 ID3D11RenderTargetView_Release(context->rtv);
235 ID3D11Texture2D_Release(context->rt);
236 IDXGISwapChain_Release(context->swapchain);
237 DestroyWindow(context->window);
239 ref = ID3D11Device_Release(context->device);
240 ok_(__FILE__, line)(!ref, "Device has %u references left.\n", ref);
243 #define create_buffer(a, b, c, d) create_buffer_(__LINE__, a, b, c, d)
244 static ID3D11Buffer *create_buffer_(unsigned int line, ID3D11Device *device,
245 unsigned int bind_flags, unsigned int size, const void *data)
247 D3D11_SUBRESOURCE_DATA resource_data = {.pSysMem = data};
248 D3D11_BUFFER_DESC buffer_desc =
250 .ByteWidth = size,
251 .Usage = D3D11_USAGE_DEFAULT,
252 .BindFlags = bind_flags,
254 ID3D11Buffer *buffer;
255 HRESULT hr;
257 hr = ID3D11Device_CreateBuffer(device, &buffer_desc, data ? &resource_data : NULL, &buffer);
258 ok_(__FILE__, line)(hr == S_OK, "Failed to create buffer, hr %#x.\n", hr);
259 return buffer;
262 #define draw_quad(context, ps_code) draw_quad_(__LINE__, context, ps_code)
263 static void draw_quad_(unsigned int line, struct test_context *context, ID3D10Blob *ps_code)
265 static const D3D11_INPUT_ELEMENT_DESC default_layout_desc[] =
267 {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
270 static const char vs_source[] =
271 "float4 main(float4 position : POSITION) : SV_POSITION\n"
272 "{\n"
273 " return position;\n"
274 "}";
276 static const struct vec2 quad[] =
278 {-1.0f, -1.0f},
279 {-1.0f, 1.0f},
280 { 1.0f, -1.0f},
281 { 1.0f, 1.0f},
284 ID3D11Device *device = context->device;
285 unsigned int stride, offset;
286 ID3D11PixelShader *ps;
287 HRESULT hr;
289 if (!context->vs)
291 ID3D10Blob *vs_code = compile_shader_(line, vs_source, "vs_4_0", 0);
293 hr = ID3D11Device_CreateInputLayout(device, default_layout_desc, ARRAY_SIZE(default_layout_desc),
294 ID3D10Blob_GetBufferPointer(vs_code), ID3D10Blob_GetBufferSize(vs_code), &context->input_layout);
295 ok_(__FILE__, line)(hr == S_OK, "Failed to create input layout, hr %#x.\n", hr);
297 hr = ID3D11Device_CreateVertexShader(device, ID3D10Blob_GetBufferPointer(vs_code),
298 ID3D10Blob_GetBufferSize(vs_code), NULL, &context->vs);
299 ok_(__FILE__, line)(hr == S_OK, "Failed to create vertex shader, hr %#x.\n", hr);
302 if (!context->vb)
303 context->vb = create_buffer_(line, device, D3D11_BIND_VERTEX_BUFFER, sizeof(quad), quad);
305 hr = ID3D11Device_CreatePixelShader(device, ID3D10Blob_GetBufferPointer(ps_code),
306 ID3D10Blob_GetBufferSize(ps_code), NULL, &ps);
307 ok_(__FILE__, line)(hr == S_OK, "Failed to create pixel shader, hr %#x.\n", hr);
309 ID3D11DeviceContext_IASetInputLayout(context->immediate_context, context->input_layout);
310 ID3D11DeviceContext_IASetPrimitiveTopology(context->immediate_context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
311 stride = sizeof(*quad);
312 offset = 0;
313 ID3D11DeviceContext_IASetVertexBuffers(context->immediate_context, 0, 1, &context->vb, &stride, &offset);
314 ID3D11DeviceContext_VSSetShader(context->immediate_context, context->vs, NULL, 0);
315 ID3D11DeviceContext_PSSetShader(context->immediate_context, ps, NULL, 0);
317 ID3D11DeviceContext_Draw(context->immediate_context, 4, 0);
319 ID3D11PixelShader_Release(ps);
322 struct readback
324 ID3D11Resource *resource;
325 D3D11_MAPPED_SUBRESOURCE map_desc;
328 static void init_readback(struct test_context *context, struct readback *rb)
330 D3D11_TEXTURE2D_DESC texture_desc;
331 HRESULT hr;
333 ID3D11Texture2D_GetDesc(context->rt, &texture_desc);
334 texture_desc.Usage = D3D11_USAGE_STAGING;
335 texture_desc.BindFlags = 0;
336 texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
337 texture_desc.MiscFlags = 0;
338 hr = ID3D11Device_CreateTexture2D(context->device, &texture_desc, NULL, (ID3D11Texture2D **)&rb->resource);
339 ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
341 ID3D11DeviceContext_CopyResource(context->immediate_context, rb->resource, (ID3D11Resource *)context->rt);
342 hr = ID3D11DeviceContext_Map(context->immediate_context, rb->resource, 0, D3D11_MAP_READ, 0, &rb->map_desc);
343 ok(hr == S_OK, "Failed to map texture, hr %#x.\n", hr);
346 static void release_readback(struct test_context *context, struct readback *rb)
348 ID3D11DeviceContext_Unmap(context->immediate_context, rb->resource, 0);
349 ID3D11Resource_Release(rb->resource);
352 static const struct vec4 *get_readback_vec4(struct readback *rb, unsigned int x, unsigned int y)
354 return (struct vec4 *)((BYTE *)rb->map_desc.pData + y * rb->map_desc.RowPitch) + x;
357 static struct vec4 get_color_vec4(struct test_context *context, unsigned int x, unsigned int y)
359 struct readback rb;
360 struct vec4 ret;
362 init_readback(context, &rb);
363 ret = *get_readback_vec4(&rb, x, y);
364 release_readback(context, &rb);
365 return ret;
368 static void test_swizzle(void)
370 static const struct vec4 uniform = {0.0303f, 0.0f, 0.0f, 0.0202f};
371 struct test_context test_context;
372 ID3D10Blob *ps_code = NULL;
373 ID3D11Buffer *cb;
374 struct vec4 v;
376 static const char ps_source[] =
377 "uniform float4 color;\n"
378 "float4 main() : SV_TARGET\n"
379 "{\n"
380 " float4 ret = color;\n"
381 " ret.gb = ret.ra;\n"
382 " ret.ra = float2(0.0101, 0.0404);\n"
383 " return ret;\n"
384 "}";
386 if (!init_test_context(&test_context))
387 return;
389 todo_wine ps_code = compile_shader(ps_source, "ps_4_0");
390 if (ps_code)
392 cb = create_buffer(test_context.device, D3D11_BIND_CONSTANT_BUFFER, sizeof(uniform), &uniform);
393 ID3D11DeviceContext_PSSetConstantBuffers(test_context.immediate_context, 0, 1, &cb);
394 draw_quad(&test_context, ps_code);
396 v = get_color_vec4(&test_context, 0, 0);
397 ok(compare_vec4(&v, 0.0101f, 0.0303f, 0.0202f, 0.0404f, 0),
398 "Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", v.x, v.y, v.z, v.w);
400 ID3D11Buffer_Release(cb);
401 ID3D10Blob_Release(ps_code);
403 release_test_context(&test_context);
406 static void test_math(void)
408 static const float uniforms[8] = {2.5f, 0.3f, 0.2f, 0.7f, 0.1f, 1.5f};
409 struct test_context test_context;
410 ID3D10Blob *ps_code = NULL;
411 ID3D11Buffer *cb;
412 struct vec4 v;
414 static const char ps_source[] =
415 "float4 main(uniform float u, uniform float v, uniform float w, uniform float x,\n"
416 " uniform float y, uniform float z) : SV_TARGET\n"
417 "{\n"
418 " return float4(x * y - z / w + --u / -v,\n"
419 " z * x / y + w / -v,\n"
420 " u + v - w,\n"
421 " x / y / w);\n"
422 "}";
424 if (!init_test_context(&test_context))
425 return;
427 todo_wine ps_code = compile_shader(ps_source, "ps_4_0");
428 if (ps_code)
430 cb = create_buffer(test_context.device, D3D11_BIND_CONSTANT_BUFFER, sizeof(uniforms), uniforms);
431 ID3D11DeviceContext_PSSetConstantBuffers(test_context.immediate_context, 0, 1, &cb);
432 draw_quad(&test_context, ps_code);
434 v = get_color_vec4(&test_context, 0, 0);
435 ok(compare_vec4(&v, -12.43f, 9.833333f, 1.6f, 35.0f, 1),
436 "Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", v.x, v.y, v.z, v.w);
438 ID3D11Buffer_Release(cb);
439 ID3D10Blob_Release(ps_code);
441 release_test_context(&test_context);
444 static void test_conditionals(void)
446 struct test_context test_context;
447 ID3D10Blob *ps_code = NULL;
448 const struct vec4 *v;
449 struct readback rb;
450 unsigned int i;
452 static const char ps_source[] =
453 "float4 main(float4 pos : SV_POSITION) : SV_TARGET\n"
454 "{\n"
455 " if(pos.x > 200.0)\n"
456 " return float4(0.1, 0.2, 0.3, 0.4);\n"
457 " else\n"
458 " return float4(0.9, 0.8, 0.7, 0.6);\n"
459 "}";
461 if (!init_test_context(&test_context))
462 return;
464 todo_wine ps_code = compile_shader(ps_source, "ps_4_0");
465 if (ps_code)
467 draw_quad(&test_context, ps_code);
468 init_readback(&test_context, &rb);
470 for (i = 0; i < 200; i += 40)
472 v = get_readback_vec4(&rb, i, 0);
473 ok(compare_vec4(v, 0.9f, 0.8f, 0.7f, 0.6f, 0),
474 "Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", v->x, v->y, v->z, v->w);
477 for (i = 240; i < 640; i += 40)
479 v = get_readback_vec4(&rb, i, 0);
480 ok(compare_vec4(v, 0.1f, 0.2f, 0.3f, 0.4f, 0),
481 "Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", v->x, v->y, v->z, v->w);
484 release_readback(&test_context, &rb);
485 ID3D10Blob_Release(ps_code);
487 release_test_context(&test_context);
490 static void test_trig(void)
492 struct test_context test_context;
493 ID3D10Blob *ps_code = NULL;
494 const struct vec4 *v;
495 struct readback rb;
496 unsigned int i;
498 static const char ps_source[] =
499 "float4 main(float4 pos : SV_POSITION) : SV_TARGET\n"
500 "{\n"
501 " return float4(sin(pos.x - 0.5), cos(pos.x - 0.5), 0, 0);\n"
502 "}";
504 if (!init_test_context(&test_context))
505 return;
507 todo_wine ps_code = compile_shader(ps_source, "ps_4_0");
508 if (ps_code)
510 draw_quad(&test_context, ps_code);
511 init_readback(&test_context, &rb);
513 for (i = 0; i < 640; i += 20)
515 v = get_readback_vec4(&rb, i, 0);
516 ok(compare_vec4(v, sinf(i), cosf(i), 0.0f, 0.0f, 8192),
517 "Test %u: Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
518 i, v->x, v->y, v->z, v->w, sinf(i), cos(i), 0.0f, 0.0f);
521 release_readback(&test_context, &rb);
522 ID3D10Blob_Release(ps_code);
524 release_test_context(&test_context);
527 static void test_sampling(void)
529 D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = {0};
530 struct test_context test_context;
531 ID3D11ShaderResourceView *srv;
532 ID3D11SamplerState *sampler;
533 ID3D10Blob *ps_code = NULL;
534 ID3D11Texture2D *texture;
535 unsigned int i;
536 struct vec4 v;
537 HRESULT hr;
539 static const char *tests[] =
541 "sampler s;\n"
542 "float4 main() : COLOR\n"
543 "{\n"
544 " return tex2D(s, float2(0.5, 0.5));\n"
545 "}",
547 "SamplerState s;\n"
548 "float4 main() : COLOR\n"
549 "{\n"
550 " return tex2D(s, float2(0.5, 0.5));\n"
551 "}",
553 "sampler2D s;\n"
554 "float4 main() : COLOR\n"
555 "{\n"
556 " return tex2D(s, float2(0.5, 0.5));\n"
557 "}",
559 "sampler s;\n"
560 "Texture2D t;\n"
561 "float4 main() : COLOR\n"
562 "{\n"
563 " return t.Sample(s, float2(0.5, 0.5));\n"
564 "}",
566 "SamplerState s;\n"
567 "Texture2D t;\n"
568 "float4 main() : COLOR\n"
569 "{\n"
570 " return t.Sample(s, float2(0.5, 0.5));\n"
571 "}",
574 static const D3D11_TEXTURE2D_DESC texture_desc =
576 .Width = 2,
577 .Height = 2,
578 .MipLevels = 1,
579 .ArraySize = 1,
580 .Format = DXGI_FORMAT_R32G32B32A32_FLOAT,
581 .SampleDesc.Count = 1,
582 .Usage = D3D11_USAGE_DEFAULT,
583 .BindFlags = D3D11_BIND_SHADER_RESOURCE,
586 static const float texture_data[] =
588 0.0f, 0.0f, 0.0f, 0.0f,
589 0.0f, 0.0f, 0.0f, 0.0f,
590 0.0f, 0.0f, 0.0f, 0.0f,
591 1.0f, 0.0f, 1.0f, 0.0f,
594 static const D3D11_SUBRESOURCE_DATA resource_data = {&texture_data, sizeof(texture_data) / 2};
596 static const D3D11_SAMPLER_DESC sampler_desc =
598 .Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR,
599 .AddressU = D3D11_TEXTURE_ADDRESS_WRAP,
600 .AddressV = D3D11_TEXTURE_ADDRESS_WRAP,
601 .AddressW = D3D11_TEXTURE_ADDRESS_WRAP,
604 static const float red[] = {1.0f, 0.0f, 0.0f, 1.0f};
606 if (!init_test_context(&test_context))
607 return;
609 hr = ID3D11Device_CreateTexture2D(test_context.device, &texture_desc, &resource_data, &texture);
610 ok(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
611 srv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
612 srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
613 srv_desc.Texture2D.MipLevels = 1;
614 hr = ID3D11Device_CreateShaderResourceView(test_context.device, (ID3D11Resource *)texture, &srv_desc, &srv);
615 ok(hr == S_OK, "Failed to create SRV, hr %#x.\n", hr);
616 ID3D11DeviceContext_PSSetShaderResources(test_context.immediate_context, 0, 1, &srv);
618 hr = ID3D11Device_CreateSamplerState(test_context.device, &sampler_desc, &sampler);
619 ok(hr == S_OK, "Failed to create sampler, hr %#x.\n", hr);
620 ID3D11DeviceContext_PSSetSamplers(test_context.immediate_context, 0, 1, &sampler);
622 for (i = 0; i < ARRAY_SIZE(tests); ++i)
624 ID3D11DeviceContext_ClearRenderTargetView(test_context.immediate_context, test_context.rtv, red);
625 todo_wine ps_code = compile_shader_flags(tests[i], "ps_4_0", D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY);
626 if (ps_code)
628 draw_quad(&test_context, ps_code);
630 v = get_color_vec4(&test_context, 0, 0);
631 todo_wine ok(compare_vec4(&v, 0.25f, 0.0f, 0.25f, 0.0f, 0),
632 "Test %u: Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", i, v.x, v.y, v.z, v.w);
634 ID3D10Blob_Release(ps_code);
638 ID3D11Texture2D_Release(texture);
639 ID3D11SamplerState_Release(sampler);
640 ID3D11ShaderResourceView_Release(srv);
641 release_test_context(&test_context);
644 static void check_type_desc(const char *prefix, const D3D11_SHADER_TYPE_DESC *type,
645 const D3D11_SHADER_TYPE_DESC *expect)
647 ok(type->Class == expect->Class, "%s: got class %#x.\n", prefix, type->Class);
648 ok(type->Type == expect->Type, "%s: got type %#x.\n", prefix, type->Type);
649 ok(type->Rows == expect->Rows, "%s: got %u rows.\n", prefix, type->Rows);
650 ok(type->Columns == expect->Columns, "%s: got %u columns.\n", prefix, type->Columns);
651 ok(type->Elements == expect->Elements, "%s: got %u elements.\n", prefix, type->Elements);
652 ok(type->Members == expect->Members, "%s: got %u members.\n", prefix, type->Members);
653 ok(type->Offset == expect->Offset, "%s: got %u members.\n", prefix, type->Members);
654 ok(!strcmp(type->Name, expect->Name), "%s: got name %s.\n", prefix, debugstr_a(type->Name));
657 static void check_resource_binding(const char *prefix, const D3D11_SHADER_INPUT_BIND_DESC *desc,
658 const D3D11_SHADER_INPUT_BIND_DESC *expect)
660 ok(!strcmp(desc->Name, expect->Name), "%s: got name %s.\n", prefix, debugstr_a(desc->Name));
661 ok(desc->Type == expect->Type, "%s: got type %#x.\n", prefix, desc->Type);
662 ok(desc->BindPoint == expect->BindPoint, "%s: got bind point %u.\n", prefix, desc->BindPoint);
663 ok(desc->BindCount == expect->BindCount, "%s: got bind count %u.\n", prefix, desc->BindCount);
664 ok(desc->uFlags == expect->uFlags, "%s: got flags %#x.\n", prefix, desc->uFlags);
665 ok(desc->ReturnType == expect->ReturnType, "%s: got return type %#x.\n", prefix, desc->ReturnType);
666 ok(desc->Dimension == expect->Dimension, "%s: got dimension %#x.\n", prefix, desc->Dimension);
667 ok(desc->NumSamples == expect->NumSamples, "%s: got multisample count %u.\n", prefix, desc->NumSamples);
670 static void test_reflection(void)
672 ID3D11ShaderReflectionConstantBuffer *cbuffer;
673 ID3D11ShaderReflectionType *type, *field;
674 D3D11_SHADER_BUFFER_DESC buffer_desc;
675 ID3D11ShaderReflectionVariable *var;
676 D3D11_SHADER_VARIABLE_DESC var_desc;
677 ID3D11ShaderReflection *reflection;
678 D3D11_SHADER_TYPE_DESC type_desc;
679 D3D11_SHADER_DESC shader_desc;
680 ID3D10Blob *code = NULL;
681 unsigned int i, j, k;
682 char prefix[40];
683 ULONG refcount;
684 HRESULT hr;
686 static const char vs_source[] =
687 "typedef uint uint_t;\n"
688 "float m;\n"
689 "\n"
690 "cbuffer b1\n"
691 "{\n"
692 " float a;\n"
693 " float2 b;\n"
694 " float4 c;\n"
695 " float d;\n"
696 " struct\n"
697 " {\n"
698 " float4 a;\n"
699 " float b;\n"
700 " float c;\n"
701 " } s;\n"
702 /* In direct contradiction to the documentation, this does not align. */
703 " bool g;\n"
704 " float h[2];\n"
705 " int i;\n"
706 " uint_t j;\n"
707 " float3x1 k;\n"
708 " row_major float3x1 l;\n"
709 "#pragma pack_matrix(row_major)\n"
710 " float3x1 o;\n"
711 " float4 p;\n"
712 " float q;\n"
713 " struct r_name {float a;} r;\n"
714 " column_major float3x1 t;\n"
715 "};\n"
716 "\n"
717 "cbuffer b5 : register(b5)\n"
718 "{\n"
719 " float4 u;\n"
720 "}\n"
721 "\n"
722 "float4 main(uniform float4 n) : SV_POSITION\n"
723 "{\n"
724 " return o._31 + m + n + u;\n"
725 "}";
727 struct shader_variable
729 D3D11_SHADER_VARIABLE_DESC var_desc;
730 D3D11_SHADER_TYPE_DESC type_desc;
731 const D3D11_SHADER_TYPE_DESC *field_types;
734 static const D3D11_SHADER_TYPE_DESC s_field_types[] =
736 {D3D_SVC_VECTOR, D3D_SVT_FLOAT, 1, 4, 0, 0, 0, "float4"},
737 {D3D_SVC_SCALAR, D3D_SVT_FLOAT, 1, 1, 0, 0, 16, "float"},
738 {D3D_SVC_SCALAR, D3D_SVT_FLOAT, 1, 1, 0, 0, 20, "float"},
741 static const D3D11_SHADER_TYPE_DESC r_field_types[] =
743 {D3D_SVC_SCALAR, D3D_SVT_FLOAT, 1, 1, 0, 0, 0, "float"},
746 static const struct shader_variable globals_vars =
747 {{"m", 0, 4, D3D_SVF_USED}, {D3D_SVC_SCALAR, D3D_SVT_FLOAT, 1, 1, 0, 0, 0, "float"}};
748 static const struct shader_variable params_vars =
749 {{"n", 0, 16, D3D_SVF_USED}, {D3D_SVC_VECTOR, D3D_SVT_FLOAT, 1, 4, 0, 0, 0, "float4"}};
750 static const struct shader_variable buffer_vars[] =
752 {{"a", 0, 4}, {D3D_SVC_SCALAR, D3D_SVT_FLOAT, 1, 1, 0, 0, 0, "float"}},
753 {{"b", 4, 8}, {D3D_SVC_VECTOR, D3D_SVT_FLOAT, 1, 2, 0, 0, 0, "float2"}},
754 {{"c", 16, 16}, {D3D_SVC_VECTOR, D3D_SVT_FLOAT, 1, 4, 0, 0, 0, "float4"}},
755 {{"d", 32, 4}, {D3D_SVC_SCALAR, D3D_SVT_FLOAT, 1, 1, 0, 0, 0, "float"}},
756 {{"s", 48, 24}, {D3D_SVC_STRUCT, D3D_SVT_VOID, 1, 6, 0, ARRAY_SIZE(s_field_types), 0, "<unnamed>"}, s_field_types},
757 {{"g", 72, 4}, {D3D_SVC_SCALAR, D3D_SVT_BOOL, 1, 1, 0, 0, 0, "bool"}},
758 {{"h", 80, 20}, {D3D_SVC_SCALAR, D3D_SVT_FLOAT, 1, 1, 2, 0, 0, "float"}},
759 {{"i", 100, 4}, {D3D_SVC_SCALAR, D3D_SVT_INT, 1, 1, 0, 0, 0, "int"}},
760 {{"j", 104, 4}, {D3D_SVC_SCALAR, D3D_SVT_UINT, 1, 1, 0, 0, 0, "uint_t"}},
761 {{"k", 112, 12}, {D3D_SVC_MATRIX_COLUMNS, D3D_SVT_FLOAT, 3, 1, 0, 0, 0, "float3x1"}},
762 {{"l", 128, 36}, {D3D_SVC_MATRIX_ROWS, D3D_SVT_FLOAT, 3, 1, 0, 0, 0, "float3x1"}},
763 {{"o", 176, 36, D3D_SVF_USED}, {D3D_SVC_MATRIX_ROWS, D3D_SVT_FLOAT, 3, 1, 0, 0, 0, "float3x1"}},
764 {{"p", 224, 16}, {D3D_SVC_VECTOR, D3D_SVT_FLOAT, 1, 4, 0, 0, 0, "float4"}},
765 {{"q", 240, 4}, {D3D_SVC_SCALAR, D3D_SVT_FLOAT, 1, 1, 0, 0, 0, "float"}},
766 {{"r", 256, 4}, {D3D_SVC_STRUCT, D3D_SVT_VOID, 1, 1, 0, ARRAY_SIZE(r_field_types), 0, "r_name"}, r_field_types},
767 {{"t", 260, 12}, {D3D_SVC_MATRIX_COLUMNS, D3D_SVT_FLOAT, 3, 1, 0, 0, 0, "float3x1"}},
769 static const struct shader_variable b5_vars =
770 {{"u", 0, 16, D3D_SVF_USED}, {D3D_SVC_VECTOR, D3D_SVT_FLOAT, 1, 4, 0, 0, 0, "float4"}};
772 static const struct
774 D3D11_SHADER_BUFFER_DESC desc;
775 const struct shader_variable *vars;
777 vs_buffers[] =
779 {{"$Globals", D3D_CT_CBUFFER, 1, 16}, &globals_vars},
780 {{"$Params", D3D_CT_CBUFFER, 1, 16}, &params_vars},
781 {{"b1", D3D_CT_CBUFFER, ARRAY_SIZE(buffer_vars), 272}, buffer_vars},
782 {{"b5", D3D_CT_CBUFFER, 1, 16}, &b5_vars},
785 static const D3D11_SHADER_INPUT_BIND_DESC vs_bindings[] =
787 {"$Globals", D3D_SIT_CBUFFER, 0, 1},
788 {"$Params", D3D_SIT_CBUFFER, 1, 1},
789 {"b1", D3D_SIT_CBUFFER, 2, 1},
790 {"b5", D3D_SIT_CBUFFER, 5, 1, D3D_SIF_USERPACKED},
793 static const char ps_source[] =
794 "texture2D a;\n"
795 "sampler c {};\n"
796 "SamplerState d {};\n"
797 "sampler e\n"
798 "{\n"
799 " Texture = a;\n"
800 " foo = bar + 2;\n"
801 "};\n"
802 "SamplerState f\n"
803 "{\n"
804 " Texture = a;\n"
805 " foo = bar + 2;\n"
806 "};\n"
807 "sampler2D g;\n"
808 "sampler b : register(s5);\n"
809 "float4 main(float2 pos : texcoord) : SV_TARGET\n"
810 "{\n"
811 " return a.Sample(b, pos) + a.Sample(c, pos) + a.Sample(d, pos) + tex2D(f, pos) + tex2D(e, pos)"
812 " + tex2D(g, pos);\n"
813 "}";
815 static const D3D11_SHADER_INPUT_BIND_DESC ps_bindings[] =
817 {"c", D3D_SIT_SAMPLER, 0, 1},
818 {"d", D3D_SIT_SAMPLER, 1, 1},
819 {"e", D3D_SIT_SAMPLER, 2, 1},
820 {"f", D3D_SIT_SAMPLER, 3, 1},
821 {"g", D3D_SIT_SAMPLER, 4, 1},
822 {"b", D3D_SIT_SAMPLER, 5, 1, D3D_SIF_USERPACKED},
823 {"f", D3D_SIT_TEXTURE, 0, 1, D3D_SIF_TEXTURE_COMPONENTS, D3D_RETURN_TYPE_FLOAT, D3D_SRV_DIMENSION_TEXTURE2D, ~0u},
824 {"e", D3D_SIT_TEXTURE, 1, 1, D3D_SIF_TEXTURE_COMPONENTS, D3D_RETURN_TYPE_FLOAT, D3D_SRV_DIMENSION_TEXTURE2D, ~0u},
825 {"g", D3D_SIT_TEXTURE, 2, 1, D3D_SIF_TEXTURE_COMPONENTS, D3D_RETURN_TYPE_FLOAT, D3D_SRV_DIMENSION_TEXTURE2D, ~0u},
826 {"a", D3D_SIT_TEXTURE, 3, 1, D3D_SIF_TEXTURE_COMPONENTS, D3D_RETURN_TYPE_FLOAT, D3D_SRV_DIMENSION_TEXTURE2D, ~0u},
829 todo_wine code = compile_shader(vs_source, "vs_5_0");
830 if (!code)
831 return;
833 hr = pD3DReflect(ID3D10Blob_GetBufferPointer(code), ID3D10Blob_GetBufferSize(code),
834 &IID_ID3D11ShaderReflection, (void **)&reflection);
835 ok(hr == S_OK, "Got hr %#x.\n", hr);
837 hr = reflection->lpVtbl->GetDesc(reflection, &shader_desc);
838 ok(hr == S_OK, "Got hr %#x.\n", hr);
839 ok(shader_desc.ConstantBuffers == ARRAY_SIZE(vs_buffers), "Got %u buffers.\n", shader_desc.ConstantBuffers);
840 ok(shader_desc.BoundResources == ARRAY_SIZE(vs_bindings), "Got %u resources.\n", shader_desc.BoundResources);
842 for (i = 0; i < ARRAY_SIZE(vs_buffers); ++i)
844 cbuffer = reflection->lpVtbl->GetConstantBufferByIndex(reflection, i);
845 hr = cbuffer->lpVtbl->GetDesc(cbuffer, &buffer_desc);
846 ok(hr == S_OK, "Test %u: got hr %#x.\n", i, hr);
847 ok(!strcmp(buffer_desc.Name, vs_buffers[i].desc.Name),
848 "Test %u: got name %s.\n", i, debugstr_a(buffer_desc.Name));
849 ok(buffer_desc.Type == vs_buffers[i].desc.Type, "Test %u: got type %#x.\n", i, buffer_desc.Type);
850 ok(buffer_desc.Variables == vs_buffers[i].desc.Variables,
851 "Test %u: got %u variables.\n", i, buffer_desc.Variables);
852 ok(buffer_desc.Size == vs_buffers[i].desc.Size, "Test %u: got size %u.\n", i, buffer_desc.Size);
853 ok(buffer_desc.uFlags == vs_buffers[i].desc.uFlags, "Test %u: got flags %#x.\n", i, buffer_desc.uFlags);
855 for (j = 0; j < buffer_desc.Variables; ++j)
857 const struct shader_variable *expect = &vs_buffers[i].vars[j];
859 var = cbuffer->lpVtbl->GetVariableByIndex(cbuffer, j);
860 hr = var->lpVtbl->GetDesc(var, &var_desc);
861 ok(hr == S_OK, "Test %u, %u: got hr %#x.\n", i, j, hr);
862 ok(!strcmp(var_desc.Name, expect->var_desc.Name),
863 "Test %u, %u: got name %s.\n", i, j, debugstr_a(var_desc.Name));
864 ok(var_desc.StartOffset == expect->var_desc.StartOffset, "Test %u, %u: got offset %u.\n",
865 i, j, var_desc.StartOffset);
866 ok(var_desc.Size == expect->var_desc.Size, "Test %u, %u: got size %u.\n", i, j, var_desc.Size);
867 ok(var_desc.uFlags == expect->var_desc.uFlags, "Test %u, %u: got flags %#x.\n", i, j, var_desc.uFlags);
868 ok(!var_desc.DefaultValue, "Test %u, %u: got default value %p.\n", i, j, var_desc.DefaultValue);
870 type = var->lpVtbl->GetType(var);
871 hr = type->lpVtbl->GetDesc(type, &type_desc);
872 ok(hr == S_OK, "Test %u, %u: got hr %#x.\n", i, j, hr);
873 sprintf(prefix, "Test %u, %u", i, j);
874 check_type_desc(prefix, &type_desc, &expect->type_desc);
876 for (k = 0; k < type_desc.Members; ++k)
878 field = type->lpVtbl->GetMemberTypeByIndex(type, k);
879 hr = field->lpVtbl->GetDesc(field, &type_desc);
880 ok(hr == S_OK, "Test %u, %u, %u: got hr %#x.\n", i, j, k, hr);
881 sprintf(prefix, "Test %u, %u, %u", i, j, k);
882 check_type_desc(prefix, &type_desc, &vs_buffers[i].vars[j].field_types[k]);
887 for (i = 0; i < ARRAY_SIZE(vs_bindings); ++i)
889 D3D11_SHADER_INPUT_BIND_DESC desc;
891 hr = reflection->lpVtbl->GetResourceBindingDesc(reflection, i, &desc);
892 ok(hr == S_OK, "Test %u: got hr %#x.\n", i, hr);
893 sprintf(prefix, "Test %u", i);
894 check_resource_binding(prefix, &desc, &vs_bindings[i]);
897 ID3D10Blob_Release(code);
898 refcount = reflection->lpVtbl->Release(reflection);
899 ok(!refcount, "Got unexpected refcount %u.\n", refcount);
901 code = compile_shader_flags(ps_source, "ps_4_0", D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY);
902 hr = pD3DReflect(ID3D10Blob_GetBufferPointer(code), ID3D10Blob_GetBufferSize(code),
903 &IID_ID3D11ShaderReflection, (void **)&reflection);
904 ok(hr == S_OK, "Got hr %#x.\n", hr);
906 hr = reflection->lpVtbl->GetDesc(reflection, &shader_desc);
907 ok(hr == S_OK, "Got hr %#x.\n", hr);
908 ok(!shader_desc.ConstantBuffers, "Got %u buffers.\n", shader_desc.ConstantBuffers);
909 ok(shader_desc.BoundResources == ARRAY_SIZE(ps_bindings), "Got %u resources.\n", shader_desc.BoundResources);
911 for (i = 0; i < shader_desc.BoundResources; ++i)
913 D3D11_SHADER_INPUT_BIND_DESC desc;
915 hr = reflection->lpVtbl->GetResourceBindingDesc(reflection, i, &desc);
916 ok(hr == S_OK, "Test %u: got hr %#x.\n", i, hr);
917 sprintf(prefix, "Test %u", i);
918 check_resource_binding(prefix, &desc, &ps_bindings[i]);
921 ID3D10Blob_Release(code);
922 refcount = reflection->lpVtbl->Release(reflection);
923 ok(!refcount, "Got unexpected refcount %u.\n", refcount);
926 static void check_parameter_desc(const char *prefix, const D3D11_SIGNATURE_PARAMETER_DESC *desc,
927 const D3D11_SIGNATURE_PARAMETER_DESC *expect)
929 ok(!strcmp(desc->SemanticName, expect->SemanticName), "%s: got name %s.\n", prefix, debugstr_a(desc->SemanticName));
930 ok(desc->SemanticIndex == expect->SemanticIndex, "%s: got index %u.\n", prefix, desc->SemanticIndex);
931 ok(desc->Register == expect->Register, "%s: got register %u.\n", prefix, desc->Register);
932 ok(desc->SystemValueType == expect->SystemValueType, "%s: got sysval %u.\n", prefix, desc->SystemValueType);
933 ok(desc->ComponentType == expect->ComponentType, "%s: got data type %u.\n", prefix, desc->ComponentType);
934 ok(desc->Mask == expect->Mask, "%s: got mask %#x.\n", prefix, desc->Mask);
935 todo_wine_if(desc->ReadWriteMask != expect->ReadWriteMask)
936 ok(desc->ReadWriteMask == expect->ReadWriteMask, "%s: got used mask %#x.\n", prefix, desc->ReadWriteMask);
937 ok(desc->Stream == expect->Stream, "%s: got stream %u.\n", prefix, desc->Stream);
940 static void test_semantic_reflection(void)
942 D3D11_SIGNATURE_PARAMETER_DESC desc;
943 ID3D11ShaderReflection *reflection;
944 D3D11_SHADER_DESC shader_desc;
945 ID3D10Blob *code = NULL;
946 unsigned int i, j;
947 char prefix[40];
948 ULONG refcount;
949 HRESULT hr;
951 static const char vs1_source[] =
952 "void main(\n"
953 " in float4 a : apple,\n"
954 " out float4 b : banana2,\n"
955 " inout float4 c : color,\n"
956 " inout float4 d : depth,\n"
957 " inout float4 e : sv_position,\n"
958 " in uint3 f : fruit,\n"
959 " inout bool2 g : grape,\n"
960 " in int h : honeydew)\n"
961 "{\n"
962 " b.yw = a.xz;\n"
963 "}";
965 static const D3D11_SIGNATURE_PARAMETER_DESC vs1_inputs[] =
967 {"apple", 0, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x5},
968 {"color", 0, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf},
969 {"depth", 0, 2, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf},
970 {"sv_position", 0, 3, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf},
971 {"fruit", 0, 4, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_UINT32, 0x7},
972 {"grape", 0, 5, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_UINT32, 0x3, 0x3},
973 {"honeydew", 0, 6, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_SINT32, 0x1},
976 static const D3D11_SIGNATURE_PARAMETER_DESC vs1_outputs[] =
978 {"banana", 2, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0x5},
979 {"color", 0, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf},
980 {"depth", 0, 2, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf},
981 {"sv_position", 0, 3, D3D_NAME_POSITION, D3D_REGISTER_COMPONENT_FLOAT32, 0xf},
982 {"grape", 0, 4, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_UINT32, 0x3, 0xc},
985 static const char vs2_source[] =
986 "void main(inout float4 pos : position)\n"
987 "{\n"
988 "}";
990 static const D3D11_SIGNATURE_PARAMETER_DESC vs2_inputs[] =
992 {"position", 0, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf},
995 static const D3D11_SIGNATURE_PARAMETER_DESC vs2_outputs[] =
997 {"position", 0, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf},
1000 static const D3D11_SIGNATURE_PARAMETER_DESC vs2_legacy_outputs[] =
1002 {"SV_Position", 0, 0, D3D_NAME_POSITION, D3D_REGISTER_COMPONENT_FLOAT32, 0xf},
1005 static const char ps1_source[] =
1006 "void main(\n"
1007 " in float2 a : apple,\n"
1008 " out float4 b : sv_target2,\n"
1009 " out float c : sv_depth,\n"
1010 " in float4 d : position,\n"
1011 " in float4 e : sv_position)\n"
1012 "{\n"
1013 " b = d;\n"
1014 " c = 0;\n"
1015 "}";
1017 static const D3D11_SIGNATURE_PARAMETER_DESC ps1_inputs[] =
1019 {"apple", 0, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0x3},
1020 {"position", 0, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf},
1021 {"sv_position", 0, 2, D3D_NAME_POSITION, D3D_REGISTER_COMPONENT_FLOAT32, 0xf},
1024 static const D3D11_SIGNATURE_PARAMETER_DESC ps1_outputs[] =
1026 {"sv_target", 2, 2, D3D_NAME_TARGET, D3D_REGISTER_COMPONENT_FLOAT32, 0xf},
1027 {"sv_depth", 0, ~0u, D3D_NAME_DEPTH, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0xe},
1030 static const char ps2_source[] =
1031 "void main(\n"
1032 " inout float4 a : color2,\n"
1033 " inout float b : depth,\n"
1034 " in float4 c : position)\n"
1035 "{\n"
1036 "}";
1038 static const D3D11_SIGNATURE_PARAMETER_DESC ps2_inputs[] =
1040 {"color", 2, 0, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf},
1041 {"depth", 0, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0x1},
1042 {"SV_Position", 0, 2, D3D_NAME_POSITION, D3D_REGISTER_COMPONENT_FLOAT32, 0xf},
1045 static const D3D11_SIGNATURE_PARAMETER_DESC ps2_outputs[] =
1047 {"SV_Target", 2, 2, D3D_NAME_TARGET, D3D_REGISTER_COMPONENT_FLOAT32, 0xf},
1048 {"SV_Depth", 0, ~0u, D3D_NAME_DEPTH, D3D_REGISTER_COMPONENT_FLOAT32, 0x1, 0xe},
1051 static const char cs1_source[] =
1052 "[numthreads(1, 1, 1)]\n"
1053 "void main(in uint a : sv_dispatchthreadid)\n"
1054 "{\n"
1055 "}";
1057 static const char gs1_source[] =
1058 "struct input\n"
1059 "{\n"
1060 " float4 a : sv_position;\n"
1061 " float4 b : apple2;\n"
1062 "};\n"
1063 "struct vertex\n"
1064 "{\n"
1065 " float4 a : sv_position;\n"
1066 " float4 b : apple2;\n"
1067 " uint c : sv_primitiveid;\n"
1068 "};\n"
1069 "[maxvertexcount(1)]\n"
1070 "void main(\n"
1071 " point input i[1],\n"
1072 " inout PointStream<vertex> o,\n"
1073 " uint a : sv_primitiveid)\n"
1074 "{\n"
1075 " struct vertex v;\n"
1076 " v.a = i[0].a;\n"
1077 " v.b = i[0].b;\n"
1078 " v.c = a;\n"
1079 " o.Append(v);\n"
1080 "}";
1082 static const D3D11_SIGNATURE_PARAMETER_DESC gs1_inputs[] =
1084 {"sv_position", 0, 0, D3D_NAME_POSITION, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf},
1085 {"apple", 2, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf, 0xf},
1086 {"sv_primitiveid", 0, ~0u, D3D_NAME_PRIMITIVE_ID, D3D_REGISTER_COMPONENT_UINT32, 0x1, 0x1},
1089 static const D3D11_SIGNATURE_PARAMETER_DESC gs1_outputs[] =
1091 {"sv_position", 0, 0, D3D_NAME_POSITION, D3D_REGISTER_COMPONENT_FLOAT32, 0xf},
1092 {"apple", 2, 1, D3D_NAME_UNDEFINED, D3D_REGISTER_COMPONENT_FLOAT32, 0xf},
1093 {"sv_primitiveid", 0, 2, D3D_NAME_PRIMITIVE_ID, D3D_REGISTER_COMPONENT_UINT32, 0x1, 0xe},
1096 static const struct
1098 const char *source;
1099 const char *target;
1100 BOOL legacy;
1101 const D3D11_SIGNATURE_PARAMETER_DESC *inputs;
1102 unsigned int input_count;
1103 const D3D11_SIGNATURE_PARAMETER_DESC *outputs;
1104 unsigned int output_count;
1106 tests[] =
1108 {vs1_source, "vs_4_0", FALSE, vs1_inputs, ARRAY_SIZE(vs1_inputs), vs1_outputs, ARRAY_SIZE(vs1_outputs)},
1109 {vs1_source, "vs_4_0", TRUE, vs1_inputs, ARRAY_SIZE(vs1_inputs), vs1_outputs, ARRAY_SIZE(vs1_outputs)},
1110 {vs2_source, "vs_4_0", FALSE, vs2_inputs, ARRAY_SIZE(vs2_inputs), vs2_outputs, ARRAY_SIZE(vs2_outputs)},
1111 {vs2_source, "vs_4_0", TRUE, vs2_inputs, ARRAY_SIZE(vs2_inputs), vs2_legacy_outputs, ARRAY_SIZE(vs2_legacy_outputs)},
1112 {ps1_source, "ps_4_0", FALSE, ps1_inputs, ARRAY_SIZE(ps1_inputs), ps1_outputs, ARRAY_SIZE(ps1_outputs)},
1113 {ps2_source, "ps_4_0", TRUE, ps2_inputs, ARRAY_SIZE(ps2_inputs), ps2_outputs, ARRAY_SIZE(ps2_outputs)},
1114 {cs1_source, "cs_4_0", FALSE, NULL, 0, NULL, 0},
1115 {gs1_source, "gs_4_0", FALSE, gs1_inputs, ARRAY_SIZE(gs1_inputs), gs1_outputs, ARRAY_SIZE(gs1_outputs)},
1118 for (i = 0; i < ARRAY_SIZE(tests); ++i)
1120 todo_wine code = compile_shader_flags(tests[i].source, tests[i].target,
1121 tests[i].legacy ? D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY : 0);
1122 if (!code)
1123 continue;
1125 hr = pD3DReflect(ID3D10Blob_GetBufferPointer(code), ID3D10Blob_GetBufferSize(code),
1126 &IID_ID3D11ShaderReflection, (void **)&reflection);
1127 ok(hr == S_OK, "Test %u: got hr %#x.\n", i, hr);
1129 hr = reflection->lpVtbl->GetDesc(reflection, &shader_desc);
1130 ok(hr == S_OK, "Test %u: got hr %#x.\n", i, hr);
1131 todo_wine ok(shader_desc.InputParameters == tests[i].input_count,
1132 "Test %u: got %u input parameters.\n", i, shader_desc.InputParameters);
1133 todo_wine ok(shader_desc.OutputParameters == tests[i].output_count,
1134 "Test %u: got %u output parameters.\n", i, shader_desc.OutputParameters);
1136 for (j = 0; j < shader_desc.InputParameters; ++j)
1138 hr = reflection->lpVtbl->GetInputParameterDesc(reflection, j, &desc);
1139 ok(hr == S_OK, "Test %u, %u: got hr %#x.\n", i, j, hr);
1140 sprintf(prefix, "Test %u, input %u", i, j);
1141 check_parameter_desc(prefix, &desc, &tests[i].inputs[j]);
1144 for (j = 0; j < shader_desc.OutputParameters; ++j)
1146 hr = reflection->lpVtbl->GetOutputParameterDesc(reflection, j, &desc);
1147 ok(hr == S_OK, "Test %u, %u: got hr %#x.\n", i, j, hr);
1148 sprintf(prefix, "Test %u, output %u", i, j);
1149 check_parameter_desc(prefix, &desc, &tests[i].outputs[j]);
1152 ID3D10Blob_Release(code);
1153 refcount = reflection->lpVtbl->Release(reflection);
1154 ok(!refcount, "Got unexpected refcount %u.\n", refcount);
1158 static BOOL load_d3dcompiler(void)
1160 HMODULE module;
1162 #if D3D_COMPILER_VERSION == 47
1163 if (!(module = LoadLibraryA("d3dcompiler_47.dll"))) return FALSE;
1164 #else
1165 if (!(module = LoadLibraryA("d3dcompiler_43.dll"))) return FALSE;
1166 #endif
1168 ppD3DCompile = (void *)GetProcAddress(module, "D3DCompile");
1169 pD3DReflect = (void *)GetProcAddress(module, "D3DReflect");
1170 return TRUE;
1173 START_TEST(hlsl_d3d11)
1175 HMODULE mod;
1177 if (!load_d3dcompiler())
1179 win_skip("Could not load DLL.\n");
1180 return;
1183 test_reflection();
1184 test_semantic_reflection();
1186 if (!(mod = LoadLibraryA("d3d11.dll")))
1188 skip("Direct3D 11 is not available.\n");
1189 return;
1191 pD3D11CreateDevice = (void *)GetProcAddress(mod, "D3D11CreateDevice");
1193 test_swizzle();
1194 test_math();
1195 test_conditionals();
1196 test_trig();
1197 test_sampling();