diff --git a/Makefile.am b/Makefile.am index 5820a8b1..da6200bb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -132,6 +132,7 @@ vkd3d_shader_tests = \ tests/hlsl/initializer-static-array.shader_test \ tests/hlsl/initializer-struct.shader_test \ tests/hlsl/intrinsic-override.shader_test \ + tests/hlsl/instance-id.shader_test \ tests/hlsl/invalid.shader_test \ tests/hlsl/inverse-trig.shader_test \ tests/hlsl/is-front-face.shader_test \ diff --git a/tests/hlsl/instance-id.shader_test b/tests/hlsl/instance-id.shader_test new file mode 100644 index 00000000..b0465670 --- /dev/null +++ b/tests/hlsl/instance-id.shader_test @@ -0,0 +1,49 @@ +[require] +shader model >= 4.0 + +[vertex shader] +struct vs_in +{ + uint instance_id : SV_InstanceId; + uint vertex_id : SV_VertexId; +}; + +struct vs_out +{ + float4 position : SV_Position; + float4 color : Color; +}; + +void main(vs_in i, out vs_out o) +{ + float2 vertices[] = + { + {0.0, 0.0}, { 0.0, 2.0}, {-2.0, 0.0}, + {0.0, 0.0}, { 2.0, 0.0}, { 0.0, 2.0}, + {0.0, 0.0}, { 0.0, -2.0}, { 2.0, 0.0}, + {0.0, 0.0}, {-2.0, 0.0}, { 0.0, -2.0}, + }; + uint pos = i.vertex_id % 3; + o.position = float4(vertices[pos + i.instance_id * 3], 0.0, 1.0); + float color = 0.25 + i.instance_id * 0.25; + o.color = float4(0.0, color, 0.0, color); +} + +[pixel shader] +struct vs_out +{ + float4 position : SV_Position; + float4 color : Color; +}; + +float4 main(vs_out i) : SV_Target +{ + return i.color; +} + +[test] +todo(sm>=6 | glsl) draw triangle list 3 4 +probe rtv 0 (160, 120) rgba (0.0, 0.25, 0.0, 0.25) +probe rtv 0 (480, 120) rgba (0.0, 0.5, 0.0, 0.5) +probe rtv 0 (480, 360) rgba (0.0, 0.75, 0.0, 0.75) +probe rtv 0 (160, 360) rgba (0.0, 1.0, 0.0, 1.0) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 8e6fdf9b..b4b440de 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -930,13 +930,13 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) if (!runner->vs_source) runner->vs_source = strdup(vs_source); - runner->last_render_failed = !runner->ops->draw(runner, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, 3); + runner->last_render_failed = !runner->ops->draw(runner, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, 3, 1); } else if (match_string(line, "draw", &line)) { + unsigned int vertex_count, instance_count; D3D_PRIMITIVE_TOPOLOGY topology; struct resource_params params; - unsigned int vertex_count; if (!runner->hs_source != !runner->ds_source) fatal_error("Have a domain or hull shader but not both.\n"); @@ -975,8 +975,11 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) vertex_count = strtoul(line, &rest, 10); if (line == rest) fatal_error("Malformed vertex count '%s'.\n", line); + instance_count = strtoul(line = rest, &rest, 10); + if (line == rest) + instance_count = 1; - runner->last_render_failed = !runner->ops->draw(runner, topology, vertex_count); + runner->last_render_failed = !runner->ops->draw(runner, topology, vertex_count, instance_count); } else if (match_string(line, "probe", &line)) { diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 5f061fa7..9d41d759 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -196,7 +196,8 @@ struct shader_runner_ops struct resource *(*create_resource)(struct shader_runner *runner, const struct resource_params *params); void (*destroy_resource)(struct shader_runner *runner, struct resource *resource); void (*clear)(struct shader_runner *runner, struct resource *resource, const struct vec4 *clear_value); - bool (*draw)(struct shader_runner *runner, D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count); + bool (*draw)(struct shader_runner *runner, D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count, + unsigned int instance_count); bool (*dispatch)(struct shader_runner *runner, unsigned int x, unsigned int y, unsigned int z); struct resource_readback *(*get_resource_readback)(struct shader_runner *runner, struct resource *resource); void (*release_readback)(struct shader_runner *runner, struct resource_readback *rb); diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index bb1d00d6..9eb8ac4e 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -634,7 +634,7 @@ static void d3d11_runner_clear(struct shader_runner *r, struct resource *res, co } static bool d3d11_runner_draw(struct shader_runner *r, - D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count) + D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count, unsigned int instance_count) { ID3D11UnorderedAccessView *uavs[D3D11_PS_CS_UAV_REGISTER_COUNT] = {0}; ID3D11RenderTargetView *rtvs[D3D11_PS_CS_UAV_REGISTER_COUNT] = {0}; @@ -812,7 +812,7 @@ static bool d3d11_runner_draw(struct shader_runner *r, ID3D11DeviceContext_DSSetShader(context, ds, NULL, 0); ID3D11DeviceContext_RSSetState(context, runner->rasterizer_state); - ID3D11DeviceContext_Draw(context, vertex_count, 0); + ID3D11DeviceContext_DrawInstanced(context, vertex_count, instance_count, 0, 0); ID3D11PixelShader_Release(ps); ID3D11VertexShader_Release(vs); diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 8119a66e..37780682 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -494,7 +494,7 @@ static void d3d12_runner_clear(struct shader_runner *r, struct resource *resourc } static bool d3d12_runner_draw(struct shader_runner *r, - D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count) + D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count, unsigned int instance_count) { struct d3d12_shader_runner *runner = d3d12_shader_runner(r); struct test_context *test_context = &runner->test_context; @@ -676,7 +676,7 @@ static bool d3d12_runner_draw(struct shader_runner *r, ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &test_context->viewport); ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, primitive_topology); ID3D12GraphicsCommandList_SetPipelineState(command_list, pso); - ID3D12GraphicsCommandList_DrawInstanced(command_list, vertex_count, 1, 0, 0); + ID3D12GraphicsCommandList_DrawInstanced(command_list, vertex_count, instance_count, 0, 0); /* Finish the command list so that we can destroy objects. */ hr = ID3D12GraphicsCommandList_Close(command_list); diff --git a/tests/shader_runner_d3d9.c b/tests/shader_runner_d3d9.c index f61a2305..d427576d 100644 --- a/tests/shader_runner_d3d9.c +++ b/tests/shader_runner_d3d9.c @@ -330,7 +330,7 @@ static void d3d9_runner_clear(struct shader_runner *r, struct resource *resource } static bool d3d9_runner_draw(struct shader_runner *r, - D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count) + D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count, unsigned int instance_count) { static const D3DVERTEXELEMENT9 decl_element_end = D3DDECL_END(); struct d3d9_shader_runner *runner = d3d9_shader_runner(r); @@ -343,6 +343,9 @@ static bool d3d9_runner_draw(struct shader_runner *r, unsigned int i, j; HRESULT hr; + if (instance_count > 1) + fatal_error("Unhandled instance count %u.\n", instance_count); + if (!(vs_code = compile_shader(runner, runner->r.vs_source, "vs"))) return false; diff --git a/tests/shader_runner_gl.c b/tests/shader_runner_gl.c index 632ba5cc..2649dc55 100644 --- a/tests/shader_runner_gl.c +++ b/tests/shader_runner_gl.c @@ -974,7 +974,7 @@ static void gl_runner_clear(struct shader_runner *r, struct resource *res, const } static bool gl_runner_draw(struct shader_runner *r, - D3D_PRIMITIVE_TOPOLOGY topology, unsigned int vertex_count) + D3D_PRIMITIVE_TOPOLOGY topology, unsigned int vertex_count, unsigned int instance_count) { struct vkd3d_shader_signature vs_input_signature; unsigned int attribute_idx, rt_count, i, j; @@ -1159,7 +1159,7 @@ static bool gl_runner_draw(struct shader_runner *r, glDisableVertexAttribArray(attribute_idx); } - glDrawArrays(get_topology_gl(topology), 0, vertex_count); + glDrawArraysInstanced(get_topology_gl(topology), 0, vertex_count, instance_count); for (i = 0; i < runner->r.sampler_count; ++i) { diff --git a/tests/shader_runner_vulkan.c b/tests/shader_runner_vulkan.c index 68a71c01..8c48c107 100644 --- a/tests/shader_runner_vulkan.c +++ b/tests/shader_runner_vulkan.c @@ -1293,7 +1293,7 @@ static void vulkan_runner_clear(struct shader_runner *r, struct resource *res, c } static bool vulkan_runner_draw(struct shader_runner *r, - D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count) + D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count, unsigned int instance_count) { struct vulkan_shader_runner *runner = vulkan_shader_runner(r); @@ -1330,7 +1330,7 @@ static bool vulkan_runner_draw(struct shader_runner *r, bind_resources(runner, VK_PIPELINE_BIND_POINT_GRAPHICS, set_layout, pipeline_layout); - VK_CALL(vkCmdDraw(cmd_buffer, vertex_count, 1, 0, 0)); + VK_CALL(vkCmdDraw(cmd_buffer, vertex_count, instance_count, 0, 0)); VK_CALL(vkCmdEndRenderPass(cmd_buffer)); end_command_buffer(runner);