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
23 #include "d3dcompiler.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
);
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
;
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
);
56 if (winetest_debug
> 1)
57 trace_(__FILE__
, line
)("%s\n", (char *)ID3D10Blob_GetBufferPointer(errors
));
58 ID3D10Blob_Release(errors
);
63 static BOOL
compare_float(float f
, float g
, unsigned int ulps
)
73 if (abs(x
- y
) > ulps
)
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
);
91 IDXGISwapChain
*swapchain
;
93 ID3D11RenderTargetView
*rtv
;
94 ID3D11DeviceContext
*immediate_context
;
96 ID3D11InputLayout
*input_layout
;
97 ID3D11VertexShader
*vs
;
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
)))
114 if (SUCCEEDED(pD3D11CreateDevice(NULL
, D3D_DRIVER_TYPE_WARP
, NULL
, 0,
115 feature_level
, ARRAY_SIZE(feature_level
), D3D11_SDK_VERSION
, &device
, NULL
, NULL
)))
117 if (SUCCEEDED(pD3D11CreateDevice(NULL
, D3D_DRIVER_TYPE_REFERENCE
, NULL
, 0,
118 feature_level
, ARRAY_SIZE(feature_level
), D3D11_SDK_VERSION
, &device
, NULL
, 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
;
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
;
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
);
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
=
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
;
184 memset(context
, 0, sizeof(*context
));
186 if (!(context
->device
= create_device()))
188 skip_(__FILE__
, line
)("Failed to create device.\n");
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
);
213 vp
.Height
= rt_height
;
216 ID3D11DeviceContext_RSSetViewports(context
->immediate_context
, 1, &vp
);
221 #define release_test_context(context) release_test_context_(__LINE__, context)
222 static void release_test_context_(unsigned int line
, struct test_context
*context
)
226 if (context
->input_layout
)
227 ID3D11InputLayout_Release(context
->input_layout
);
229 ID3D11VertexShader_Release(context
->vs
);
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
=
251 .Usage
= D3D11_USAGE_DEFAULT
,
252 .BindFlags
= bind_flags
,
254 ID3D11Buffer
*buffer
;
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
);
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"
273 " return position;\n"
276 static const struct vec2 quad
[] =
284 ID3D11Device
*device
= context
->device
;
285 unsigned int stride
, offset
;
286 ID3D11PixelShader
*ps
;
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
);
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
);
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
);
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
;
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
)
362 init_readback(context
, &rb
);
363 ret
= *get_readback_vec4(&rb
, x
, y
);
364 release_readback(context
, &rb
);
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
;
376 static const char ps_source
[] =
377 "uniform float4 color;\n"
378 "float4 main() : SV_TARGET\n"
380 " float4 ret = color;\n"
381 " ret.gb = ret.ra;\n"
382 " ret.ra = float2(0.0101, 0.0404);\n"
386 if (!init_test_context(&test_context
))
389 todo_wine ps_code
= compile_shader(ps_source
, "ps_4_0");
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
;
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"
418 " return float4(x * y - z / w + --u / -v,\n"
419 " z * x / y + w / -v,\n"
424 if (!init_test_context(&test_context
))
427 todo_wine ps_code
= compile_shader(ps_source
, "ps_4_0");
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
;
452 static const char ps_source
[] =
453 "float4 main(float4 pos : SV_POSITION) : SV_TARGET\n"
455 " if(pos.x > 200.0)\n"
456 " return float4(0.1, 0.2, 0.3, 0.4);\n"
458 " return float4(0.9, 0.8, 0.7, 0.6);\n"
461 if (!init_test_context(&test_context
))
464 todo_wine ps_code
= compile_shader(ps_source
, "ps_4_0");
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
;
498 static const char ps_source
[] =
499 "float4 main(float4 pos : SV_POSITION) : SV_TARGET\n"
501 " return float4(sin(pos.x - 0.5), cos(pos.x - 0.5), 0, 0);\n"
504 if (!init_test_context(&test_context
))
507 todo_wine ps_code
= compile_shader(ps_source
, "ps_4_0");
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
;
539 static const char *tests
[] =
542 "float4 main() : COLOR\n"
544 " return tex2D(s, float2(0.5, 0.5));\n"
548 "float4 main() : COLOR\n"
550 " return tex2D(s, float2(0.5, 0.5));\n"
554 "float4 main() : COLOR\n"
556 " return tex2D(s, float2(0.5, 0.5));\n"
561 "float4 main() : COLOR\n"
563 " return t.Sample(s, float2(0.5, 0.5));\n"
568 "float4 main() : COLOR\n"
570 " return t.Sample(s, float2(0.5, 0.5));\n"
574 static const D3D11_TEXTURE2D_DESC texture_desc
=
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
))
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
);
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
;
686 static const char vs_source
[] =
687 "typedef uint uint_t;\n"
702 /* In direct contradiction to the documentation, this does not align. */
708 " row_major float3x1 l;\n"
709 "#pragma pack_matrix(row_major)\n"
713 " struct r_name {float a;} r;\n"
714 " column_major float3x1 t;\n"
717 "cbuffer b5 : register(b5)\n"
722 "float4 main(uniform float4 n) : SV_POSITION\n"
724 " return o._31 + m + n + u;\n"
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"}};
774 D3D11_SHADER_BUFFER_DESC desc
;
775 const struct shader_variable
*vars
;
779 {{"$Globals", D3D_CT_CBUFFER
, 1, 16}, &globals_vars
},
780 {{"$Params", D3D_CT_CBUFFER
, 1, 16}, ¶ms_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
[] =
796 "SamplerState d {};\n"
808 "sampler b : register(s5);\n"
809 "float4 main(float2 pos : texcoord) : SV_TARGET\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"
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");
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
;
951 static const char vs1_source
[] =
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"
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"
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
[] =
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"
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
[] =
1032 " inout float4 a : color2,\n"
1033 " inout float b : depth,\n"
1034 " in float4 c : position)\n"
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"
1057 static const char gs1_source
[] =
1060 " float4 a : sv_position;\n"
1061 " float4 b : apple2;\n"
1065 " float4 a : sv_position;\n"
1066 " float4 b : apple2;\n"
1067 " uint c : sv_primitiveid;\n"
1069 "[maxvertexcount(1)]\n"
1071 " point input i[1],\n"
1072 " inout PointStream<vertex> o,\n"
1073 " uint a : sv_primitiveid)\n"
1075 " struct vertex v;\n"
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},
1101 const D3D11_SIGNATURE_PARAMETER_DESC
*inputs
;
1102 unsigned int input_count
;
1103 const D3D11_SIGNATURE_PARAMETER_DESC
*outputs
;
1104 unsigned int output_count
;
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);
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)
1162 #if D3D_COMPILER_VERSION == 47
1163 if (!(module
= LoadLibraryA("d3dcompiler_47.dll"))) return FALSE
;
1165 if (!(module
= LoadLibraryA("d3dcompiler_43.dll"))) return FALSE
;
1168 ppD3DCompile
= (void *)GetProcAddress(module
, "D3DCompile");
1169 pD3DReflect
= (void *)GetProcAddress(module
, "D3DReflect");
1173 START_TEST(hlsl_d3d11
)
1177 if (!load_d3dcompiler())
1179 win_skip("Could not load DLL.\n");
1184 test_semantic_reflection();
1186 if (!(mod
= LoadLibraryA("d3d11.dll")))
1188 skip("Direct3D 11 is not available.\n");
1191 pD3D11CreateDevice
= (void *)GetProcAddress(mod
, "D3D11CreateDevice");
1195 test_conditionals();