Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- v2: Fixed double release of input layout. --- dlls/d3d11/tests/d3d11.c | 88 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index c499aa5f75b..9d8c0d7ebe1 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -17157,6 +17157,93 @@ static void test_shader_stage_input_output_matching(void) release_test_context(&test_context); }
+static void test_unbound_streams(void) +{ + struct d3d11_test_context test_context; + ID3D11DeviceContext *context; + ID3D11PixelShader *ps; + ID3D11Device *device; + HRESULT hr; + + static const DWORD vs_code[] = + { +#if 0 + struct vs_ps + { + float4 position : SV_POSITION; + float4 color : COLOR0; + }; + + vs_ps vs_main(float4 position : POSITION, float4 color : COLOR0) + { + vs_ps result; + result.position = position; + result.color = color; + result.color.w = 1.0; + return result; + } +#endif + 0x43425844, 0x4a9efaec, 0xe2c6cdf5, 0x15dd28a7, 0xae68e320, 0x00000001, 0x00000154, 0x00000003, + 0x0000002c, 0x0000007c, 0x000000d0, 0x4e475349, 0x00000048, 0x00000002, 0x00000008, 0x00000038, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x0000070f, 0x49534f50, 0x4e4f4954, 0x4c4f4300, 0xab00524f, 0x4e47534f, + 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x505f5653, + 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x52444853, 0x0000007c, 0x00010040, 0x0000001f, + 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x00101072, 0x00000001, 0x04000067, 0x001020f2, + 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x001020f2, 0x00000000, + 0x00101e46, 0x00000000, 0x05000036, 0x00102072, 0x00000001, 0x00101246, 0x00000001, 0x05000036, + 0x00102082, 0x00000001, 0x00004001, 0x3f800000, 0x0100003e, + }; + + static const DWORD ps_code[] = + { +#if 0 + float4 ps_main(vs_ps input) : SV_TARGET + { + return input.color; + } +#endif + 0x43425844, 0xe2087fa6, 0xa35fbd95, 0x8e585b3f, 0x67890f54, 0x00000001, 0x000000f4, 0x00000003, + 0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, + 0x0000000e, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, + 0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e, + }; + + static const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + + static const D3D11_INPUT_ELEMENT_DESC layout_desc[] = + { + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 16, D3D11_INPUT_PER_VERTEX_DATA, 0}, + }; + + if (!init_test_context(&test_context, NULL)) + return; + + device = test_context.device; + context = test_context.immediate_context; + + hr = ID3D11Device_CreatePixelShader(device, ps_code, sizeof(ps_code), NULL, &ps); + ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); + + hr = ID3D11Device_CreateInputLayout(device, layout_desc, ARRAY_SIZE(layout_desc), + vs_code, sizeof(vs_code), &test_context.input_layout); + ok(SUCCEEDED(hr), "Failed to create input layout, hr %#x.\n", hr); + + ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0); + ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, white); + draw_quad_vs(&test_context, vs_code, sizeof(vs_code)); + check_texture_color(test_context.backbuffer, 0xff000000, 1); + + ID3D11PixelShader_Release(ps); + release_test_context(&test_context); +} + static void test_shader_interstage_interface(void) { struct d3d11_test_context test_context; @@ -32520,6 +32607,7 @@ START_TEST(d3d11) queue_test(test_deferred_context_state); queue_test(test_deferred_context_swap_state); queue_test(test_deferred_context_rendering); + queue_test(test_unbound_streams);
run_queued_tests(); }
Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- v2: Fixed double release of input layout, removed skip() on pre-win7. --- dlls/d3d10core/tests/d3d10core.c | 86 ++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+)
diff --git a/dlls/d3d10core/tests/d3d10core.c b/dlls/d3d10core/tests/d3d10core.c index e0cb40de89b..d9ea568d44c 100644 --- a/dlls/d3d10core/tests/d3d10core.c +++ b/dlls/d3d10core/tests/d3d10core.c @@ -18822,6 +18822,91 @@ static void test_dual_source_blend(void) release_test_context(&test_context); }
+static void test_unbound_streams(void) +{ + struct d3d10core_test_context test_context; + ID3D10PixelShader *ps; + ID3D10Device *device; + HRESULT hr; + + static const DWORD vs_code[] = + { +#if 0 + struct vs_ps + { + float4 position : SV_POSITION; + float4 color : COLOR0; + }; + + vs_ps vs_main(float4 position : POSITION, float4 color : COLOR0) + { + vs_ps result; + result.position = position; + result.color = color; + result.color.w = 1.0; + return result; + } +#endif + 0x43425844, 0x4a9efaec, 0xe2c6cdf5, 0x15dd28a7, 0xae68e320, 0x00000001, 0x00000154, 0x00000003, + 0x0000002c, 0x0000007c, 0x000000d0, 0x4e475349, 0x00000048, 0x00000002, 0x00000008, 0x00000038, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x0000070f, 0x49534f50, 0x4e4f4954, 0x4c4f4300, 0xab00524f, 0x4e47534f, + 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000, + 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x505f5653, + 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x52444853, 0x0000007c, 0x00010040, 0x0000001f, + 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x00101072, 0x00000001, 0x04000067, 0x001020f2, + 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x001020f2, 0x00000000, + 0x00101e46, 0x00000000, 0x05000036, 0x00102072, 0x00000001, 0x00101246, 0x00000001, 0x05000036, + 0x00102082, 0x00000001, 0x00004001, 0x3f800000, 0x0100003e, + }; + + static const DWORD ps_code[] = + { +#if 0 + float4 ps_main(vs_ps input) : SV_TARGET + { + return input.color; + } +#endif + 0x43425844, 0xe2087fa6, 0xa35fbd95, 0x8e585b3f, 0x67890f54, 0x00000001, 0x000000f4, 0x00000003, + 0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, + 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040, + 0x0000000e, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x05000036, + 0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e, + }; + + static const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + + static const D3D10_INPUT_ELEMENT_DESC layout_desc[] = + { + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 16, D3D10_INPUT_PER_VERTEX_DATA, 0}, + }; + + if (!init_test_context(&test_context)) + return; + + device = test_context.device; + + hr = ID3D10Device_CreatePixelShader(device, ps_code, sizeof(ps_code), &ps); + ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr); + + hr = ID3D10Device_CreateInputLayout(device, layout_desc, ARRAY_SIZE(layout_desc), + vs_code, sizeof(vs_code), &test_context.input_layout); + ok(SUCCEEDED(hr), "Failed to create input layout, hr %#x.\n", hr); + + ID3D10Device_PSSetShader(device, ps); + ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, white); + draw_quad_vs(&test_context, vs_code, sizeof(vs_code)); + check_texture_color(test_context.backbuffer, 0xff000000, 1); + + ID3D10PixelShader_Release(ps); + release_test_context(&test_context); +} + START_TEST(d3d10core) { unsigned int argc, i; @@ -18946,6 +19031,7 @@ START_TEST(d3d10core) queue_test(test_color_mask); queue_test(test_independent_blend); queue_test(test_dual_source_blend); + queue_test(test_unbound_streams);
run_queued_tests();
Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- dlls/wined3d/context.c | 6 +++--- dlls/wined3d/context_vk.c | 2 +- dlls/wined3d/device.c | 2 +- dlls/wined3d/wined3d_private.h | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 2debf50de7f..f2fdcddc261 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -154,7 +154,7 @@ static BOOL fixed_get_input(BYTE usage, BYTE usage_idx, unsigned int *regnum)
/* Context activation is done by the caller. */ void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_info, - const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info) + const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, bool require_buffer) { /* We need to deal with frequency data! */ struct wined3d_vertex_declaration *declaration = state->vertex_declaration; @@ -182,7 +182,7 @@ void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_inf TRACE("%p Element %p (%u of %u).\n", declaration->elements, element, i + 1, declaration->element_count);
- if (!stream->buffer) + if (!stream->buffer && require_buffer) continue;
TRACE("offset %u input_slot %u usage_idx %d.\n", element->offset, element->input_slot, element->usage_idx); @@ -269,7 +269,7 @@ void context_update_stream_info(struct wined3d_context *context, const struct wi unsigned int i; WORD map;
- wined3d_stream_info_from_declaration(stream_info, state, d3d_info); + wined3d_stream_info_from_declaration(stream_info, state, d3d_info, true);
stream_info->all_vbo = 1; for (i = 0, map = stream_info->use_map; map; map >>= 1, ++i) diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 45133eabb69..6d168515358 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -2032,7 +2032,7 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_STREAMSRC) || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX))) { - wined3d_stream_info_from_declaration(&stream_info, state, d3d_info); + wined3d_stream_info_from_declaration(&stream_info, state, d3d_info, true); divisor_count = 0; for (i = 0, mask = 0, attribute_count = 0, binding_count = 0; i < ARRAY_SIZE(stream_info.elements); ++i) { diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 974db90037d..eb718c7bf07 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3797,7 +3797,7 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device,
vs = state->shader[WINED3D_SHADER_TYPE_VERTEX]; state->shader[WINED3D_SHADER_TYPE_VERTEX] = NULL; - wined3d_stream_info_from_declaration(&stream_info, state, &device->adapter->d3d_info); + wined3d_stream_info_from_declaration(&stream_info, state, &device->adapter->d3d_info, true); state->shader[WINED3D_SHADER_TYPE_VERTEX] = vs;
/* We can't convert FROM a VBO, and vertex buffers used to source into diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c3e3752ed71..8c9f34dc08a 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1678,7 +1678,8 @@ struct wined3d_stream_info };
void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_info, - const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN; + const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, + bool require_buffer) DECLSPEC_HIDDEN;
struct wined3d_direct_dispatch_parameters {
On Fri, 16 Apr 2021 at 10:45, Jan Sikorski jsikorski@codeweavers.com wrote:
/* Context activation is done by the caller. */ void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_info,
const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info)
const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, bool require_buffer)
{ /* We need to deal with frequency data! */ struct wined3d_vertex_declaration *declaration = state->vertex_declaration; @@ -182,7 +182,7 @@ void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_inf TRACE("%p Element %p (%u of %u).\n", declaration->elements, element, i + 1, declaration->element_count);
if (!stream->buffer)
if (!stream->buffer && require_buffer) continue;
Would it make sense to drop the "require_buffer" argument and just always behave as if it's false?
On 16 Apr 2021, at 16:01, Henri Verbeet hverbeet@gmail.com wrote:
On Fri, 16 Apr 2021 at 10:45, Jan Sikorski jsikorski@codeweavers.com wrote:
/* Context activation is done by the caller. */ void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_info,
const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info)
const struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, bool require_buffer)
{ /* We need to deal with frequency data! */ struct wined3d_vertex_declaration *declaration = state->vertex_declaration; @@ -182,7 +182,7 @@ void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_inf TRACE("%p Element %p (%u of %u).\n", declaration->elements, element, i + 1, declaration->element_count);
if (!stream->buffer)
if (!stream->buffer && require_buffer) continue;
Would it make sense to drop the "require_buffer" argument and just always behave as if it's false?
Maybe. It looked pretty annoying to do so, there would be 3 checks in wined3d_device_process_vertices() alone, and some more scattered around where struct's wined3d_context stream_info member is used. Perhaps it is slightly hacky as such, but since OpenGL handles unbound streams automatically, ignoring them early seemed adequate, plus it has the benefit of not changing existing behavior ;) I’ll have to look at it some more to be sure, but if I’m going get this information from the shader signature instead, I don’t think this change will be necessary (i.e. ok to always require buffer here).
- Jan
Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- dlls/wined3d/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index eb718c7bf07..c4decc510f2 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -652,7 +652,7 @@ bool wined3d_device_vk_create_null_resources(struct wined3d_device_vk *device_vk vk_info = context_vk->vk_info;
usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT - | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; memory_type = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; if (!wined3d_context_vk_create_bo(context_vk, 16, usage, memory_type, &r->bo)) return false;
Since we're not using the nullDescriptor feature, we need to bind an actual buffer for all bindings that are accessed by the shader (VUID-vkCmdDraw-None-04007). If there's no buffer set for a stream, bind the null buffer instead.
Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- dlls/wined3d/context_vk.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 6d168515358..ae7107dc1c8 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -2322,27 +2322,43 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont static void wined3d_context_vk_bind_vertex_buffers(struct wined3d_context_vk *context_vk, VkCommandBuffer vk_command_buffer, const struct wined3d_state *state, const struct wined3d_vk_info *vk_info) { + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); VkDeviceSize offsets[ARRAY_SIZE(state->streams)] = {0}; - VkBuffer buffers[ARRAY_SIZE(state->streams)]; + VkBuffer buffers[ARRAY_SIZE(state->streams)] = {0}; + struct wined3d_graphics_pipeline_key_vk *key; const struct wined3d_stream_state *stream; const VkDescriptorBufferInfo *buffer_info; + unsigned int i, first, count, binding; struct wined3d_buffer_vk *buffer_vk; struct wined3d_buffer *buffer; - unsigned int i, first, count;
- first = 0; - count = 0; - for (i = 0; i < ARRAY_SIZE(state->streams); ++i) + key = &context_vk->graphics.pipeline_key_vk; + for (i = 0; i < key->input_desc.vertexBindingDescriptionCount; ++i) { - stream = &state->streams[i]; - + binding = key->bindings[i].binding; + stream = &state->streams[binding]; if ((buffer = stream->buffer)) { buffer_vk = wined3d_buffer_vk(buffer); buffer_info = wined3d_buffer_vk_get_buffer_info(buffer_vk); wined3d_context_vk_reference_bo(context_vk, &buffer_vk->bo); - buffers[count] = buffer_info->buffer; - offsets[count] = buffer_info->offset + stream->offset; + } + else + { + buffer_info = &device_vk->null_resources_vk.buffer_info; + wined3d_context_vk_reference_bo(context_vk, &device_vk->null_resources_vk.bo); + } + + buffers[binding] = buffer_info->buffer; + offsets[binding] = buffer_info->offset + stream->offset; + } + + first = 0; + count = 0; + for (i = 0; i < ARRAY_SIZE(state->streams); ++i) + { + if (buffers[i]) + { ++count; continue; }
Fix them to be VK_VERTEX_INPUT_RATE_VERTEX with zero stride and offset, as they will get a zero-filled buffer with a fixed size bound to them. We could maybe avoid changing the pipeline key in that case with the nullDescriptor feature. This is left as a potential future improvement.
Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- dlls/wined3d/context_vk.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index ae7107dc1c8..02b03be915f 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -2032,7 +2032,7 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_STREAMSRC) || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX))) { - wined3d_stream_info_from_declaration(&stream_info, state, d3d_info, true); + wined3d_stream_info_from_declaration(&stream_info, state, d3d_info, false); divisor_count = 0; for (i = 0, mask = 0, attribute_count = 0, binding_count = 0; i < ARRAY_SIZE(stream_info.elements); ++i) { @@ -2041,6 +2041,7 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte VkVertexInputAttributeDescription *a; VkVertexInputBindingDescription *b; uint32_t binding; + bool empty;
if (!(stream_info.use_map & (1u << i))) continue; @@ -2048,11 +2049,12 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte a = &key->attributes[attribute_count++]; e = &stream_info.elements[i]; binding = e->stream_idx; + empty = !state->streams[binding].buffer;
a->location = i; a->binding = binding; a->format = wined3d_format_vk(e->format)->vk_format; - a->offset = (UINT_PTR)e->data.addr - state->streams[binding].offset; + a->offset = empty ? 0 : (UINT_PTR)e->data.addr - state->streams[binding].offset;
if (mask & (1u << binding)) continue; @@ -2060,11 +2062,13 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte
b = &key->bindings[binding_count++]; b->binding = binding; - b->stride = e->stride; - b->inputRate = e->instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; + b->stride = empty ? 0 : e->stride;
- if (e->instanced) + if (!e->instanced || empty) + b->inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + else { + b->inputRate = VK_VERTEX_INPUT_RATE_INSTANCE; d = &key->divisors[divisor_count++]; d->binding = binding; d->divisor = e->divisor;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=88836
Your paranoid android.
=== w10pro64 (32 bit report) ===
d3d11: d3d11.c:5811: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5812: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5813: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5817: Test failed: Got unexpected CPrimitives count: 0. d3d11.c:5835: Test failed: Got unexpected PSInvocations count: 0.
On Fri, 16 Apr 2021 at 10:45, Jan Sikorski jsikorski@codeweavers.com wrote:
- hr = ID3D11Device_CreateInputLayout(device, layout_desc, ARRAY_SIZE(layout_desc),
vs_code, sizeof(vs_code), &test_context.input_layout);
- ok(SUCCEEDED(hr), "Failed to create input layout, hr %#x.\n", hr);
Some quick testing (i.e., getting rid of input layout creation here, and creating the input layout in draw_quad_vs_() against default_vs_code[]) seems to suggest this also works without a matching input layout. Should we perhaps look at the shader input signature instead?
On 16 Apr 2021, at 16:01, Henri Verbeet hverbeet@gmail.com wrote:
On Fri, 16 Apr 2021 at 10:45, Jan Sikorski jsikorski@codeweavers.com wrote:
- hr = ID3D11Device_CreateInputLayout(device, layout_desc, ARRAY_SIZE(layout_desc),
vs_code, sizeof(vs_code), &test_context.input_layout);
- ok(SUCCEEDED(hr), "Failed to create input layout, hr %#x.\n", hr);
Some quick testing (i.e., getting rid of input layout creation here, and creating the input layout in draw_quad_vs_() against default_vs_code[]) seems to suggest this also works without a matching input layout. Should we perhaps look at the shader input signature instead?
That works, but gave me a validation error: D3D11 ERROR: ID3D11DeviceContext::Draw: Input Assembler - Vertex Shader linkage error: Signatures between stages are incompatible. The input stage requires Semantic/Index (COLOR,0) as input, but it is not provided by the output stage. [ EXECUTION ERROR #342: DEVICE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND]
It looks like an extra complication to match against the shader signature, I’m not sure if there are other reasons to prefer that?
- Jan
On Mon, 19 Apr 2021 at 16:24, Jan Sikorski jsikorski@codeweavers.com wrote:
On 16 Apr 2021, at 16:01, Henri Verbeet hverbeet@gmail.com wrote: Some quick testing (i.e., getting rid of input layout creation here, and creating the input layout in draw_quad_vs_() against default_vs_code[]) seems to suggest this also works without a matching input layout. Should we perhaps look at the shader input signature instead?
That works, but gave me a validation error: D3D11 ERROR: ID3D11DeviceContext::Draw: Input Assembler - Vertex Shader linkage error: Signatures between stages are incompatible. The input stage requires Semantic/Index (COLOR,0) as input, but it is not provided by the output stage. [ EXECUTION ERROR #342: DEVICE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND]
It looks like an extra complication to match against the shader signature, I’m not sure if there are other reasons to prefer that?
It seems simpler in some regards. E.g., in wined3d_stream_info_from_declaration(), after the loop over the declaration elements, you'd loop over the shader's input signature, and insert entries for inputs not already setup, instead of using the "require_buffer" parameter.
On 19 Apr 2021, at 17:00, Henri Verbeet hverbeet@gmail.com wrote:
On Mon, 19 Apr 2021 at 16:24, Jan Sikorski jsikorski@codeweavers.com wrote:
On 16 Apr 2021, at 16:01, Henri Verbeet hverbeet@gmail.com wrote: Some quick testing (i.e., getting rid of input layout creation here, and creating the input layout in draw_quad_vs_() against default_vs_code[]) seems to suggest this also works without a matching input layout. Should we perhaps look at the shader input signature instead?
That works, but gave me a validation error: D3D11 ERROR: ID3D11DeviceContext::Draw: Input Assembler - Vertex Shader linkage error: Signatures between stages are incompatible. The input stage requires Semantic/Index (COLOR,0) as input, but it is not provided by the output stage. [ EXECUTION ERROR #342: DEVICE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND]
It looks like an extra complication to match against the shader signature, I’m not sure if there are other reasons to prefer that?
It seems simpler in some regards. E.g., in wined3d_stream_info_from_declaration(), after the loop over the declaration elements, you'd loop over the shader's input signature, and insert entries for inputs not already setup, instead of using the "require_buffer" parameter.
Yeah, the part I’m missing is the mapping between wined3d_shader_signature_element and stream index / binding / location. Maybe it’s just something simple that I didn’t find?
On Mon, 19 Apr 2021 at 17:24, Jan Sikorski jsikorski@codeweavers.com wrote:
Yeah, the part I’m missing is the mapping between wined3d_shader_signature_element and stream index / binding / location. Maybe it’s just something simple that I didn’t find?
Do you mean for wined3d_context_vk_bind_vertex_buffers() and the binding number in VkVertexInputAttributeDescription? It seems a little unfortunate, but perhaps the most convenient thing to do would be to find the first NULL buffer in state->streams[], and use that as the stream index for NULL bindings.