Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- tests/shader_runner.c | 15 +++++++++++++++ tests/shader_runner.h | 1 + tests/shader_runner_d3d11.c | 2 +- tests/shader_runner_d3d12.c | 38 +++++++++++++++++++++++++------------ 4 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 910e6ecdc..033fee0a6 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -80,6 +80,7 @@ enum parse_state STATE_SAMPLER, STATE_SHADER_INVALID_PIXEL, STATE_SHADER_PIXEL, + STATE_SHADER_VERTEX, STATE_TEXTURE, STATE_TEST, }; @@ -501,6 +502,14 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const shader_source_size = 0; break;
+ case STATE_SHADER_VERTEX: + free(runner->vs_source); + runner->vs_source = shader_source; + shader_source = NULL; + shader_source_len = 0; + shader_source_size = 0; + break; + case STATE_SHADER_INVALID_PIXEL: { ID3D10Blob *blob = NULL, *errors = NULL; @@ -639,6 +648,10 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const { state = STATE_PREPROC_INVALID; } + else if (!strcmp(line, "[vertex shader]\n")) + { + state = STATE_SHADER_VERTEX; + }
vkd3d_test_set_context("Section %.*s, line %u", strlen(line) - 1, line, line_number); } @@ -654,6 +667,7 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const case STATE_PREPROC_INVALID: case STATE_SHADER_INVALID_PIXEL: case STATE_SHADER_PIXEL: + case STATE_SHADER_VERTEX: { size_t len = strlen(line);
@@ -682,6 +696,7 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const } }
+ free(runner->vs_source); free(runner->ps_source); for (i = 0; i < runner->texture_count; ++i) { diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 26fa2367b..43ded8534 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -72,6 +72,7 @@ struct shader_runner { const struct shader_runner_ops *ops;
+ char *vs_source; char *ps_source; enum shader_model minimum_shader_model;
diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index c077718c9..fb73f80e9 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -434,7 +434,7 @@ static void d3d11_runner_draw_quad(struct shader_runner *r)
if (!runner->vs) { - ID3D10Blob *vs_code = compile_shader(vs_source, "vs_4_0"); + ID3D10Blob *vs_code = compile_shader(runner->r.vs_source ? runner->r.vs_source : vs_source, "vs_4_0");
hr = ID3D11Device_CreateVertexShader(device, ID3D10Blob_GetBufferPointer(vs_code), ID3D10Blob_GetBufferSize(vs_code), NULL, &runner->vs); diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 4f077b382..e124922fa 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -52,22 +52,23 @@ static struct d3d12_shader_runner *d3d12_shader_runner(struct shader_runner *r) return CONTAINING_RECORD(r, struct d3d12_shader_runner, r); }
-static ID3D10Blob *compile_shader(const char *source, enum shader_model shader_model) +static ID3D10Blob *compile_shader(const char *source, const char *type, enum shader_model shader_model) { ID3D10Blob *blob = NULL, *errors = NULL; + char profile[7]; HRESULT hr;
static const char *const shader_models[] = { - [SHADER_MODEL_2_0] = "ps_4_0", - [SHADER_MODEL_4_0] = "ps_4_0", - [SHADER_MODEL_4_1] = "ps_4_1", - [SHADER_MODEL_5_0] = "ps_5_0", - [SHADER_MODEL_5_1] = "ps_5_1", + [SHADER_MODEL_2_0] = "4_0", + [SHADER_MODEL_4_0] = "4_0", + [SHADER_MODEL_4_1] = "4_1", + [SHADER_MODEL_5_0] = "5_0", + [SHADER_MODEL_5_1] = "5_1", };
- hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", - shader_models[shader_model], 0, 0, &blob, &errors); + sprintf(profile, "%s_%s", type, shader_models[shader_model]); + hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", profile, 0, 0, &blob, &errors); ok(hr == S_OK, "Failed to compile shader, hr %#x.\n", hr); if (errors) { @@ -132,17 +133,23 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) ID3D12CommandQueue *queue = test_context->queue; D3D12_STATIC_SAMPLER_DESC static_samplers[1]; ID3D12Device *device = test_context->device; + ID3D10Blob *vs_code = NULL, *ps_code; static const float clear_color[4]; + D3D12_SHADER_BYTECODE vs, ps; unsigned int uniform_index; - D3D12_SHADER_BYTECODE ps; ID3D12PipelineState *pso; - ID3D10Blob *ps_code; HRESULT hr; size_t i;
- if (!(ps_code = compile_shader(runner->r.ps_source, runner->r.minimum_shader_model))) + if (!(ps_code = compile_shader(runner->r.ps_source, "ps", runner->r.minimum_shader_model))) return;
+ if (runner->r.vs_source && !(vs_code = compile_shader(runner->r.vs_source, "vs", runner->r.minimum_shader_model))) + { + ID3D10Blob_Release(ps_code); + return; + } + root_signature_desc.NumParameters = 0; root_signature_desc.pParameters = root_params; root_signature_desc.NumStaticSamplers = 0; @@ -202,10 +209,17 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) hr = create_root_signature(device, &root_signature_desc, &test_context->root_signature); ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
+ if (vs_code) + { + vs.pShaderBytecode = ID3D10Blob_GetBufferPointer(vs_code); + vs.BytecodeLength = ID3D10Blob_GetBufferSize(vs_code); + } ps.pShaderBytecode = ID3D10Blob_GetBufferPointer(ps_code); ps.BytecodeLength = ID3D10Blob_GetBufferSize(ps_code); pso = create_pipeline_state(device, test_context->root_signature, - test_context->render_target_desc.Format, NULL, &ps, NULL); + test_context->render_target_desc.Format, vs_code ? &vs : NULL, &ps, NULL); + if (vs_code) + ID3D10Blob_Release(vs_code); ID3D10Blob_Release(ps_code); if (!pso) return;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- tests/shader_runner.c | 10 +++++++ tests/shader_runner_d3d11.c | 54 ++++++++++++++++--------------------- tests/shader_runner_d3d12.c | 16 +++++------ 3 files changed, 39 insertions(+), 41 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 033fee0a6..a2aecf9f9 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -290,6 +290,16 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) { if (match_string(line, "draw quad", &line)) { + static const char vs_source[] = + "void main(uint id : SV_VertexID, out float4 position : SV_Position)\n" + "{\n" + " float2 coords = float2((id << 1) & 2, id & 2);\n" + " position = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1);\n" + "}"; + + if (!runner->vs_source) + runner->vs_source = strdup(vs_source); + runner->ops->draw_quad(runner); } else if (match_string(line, "probe all rgba", &line)) diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index fb73f80e9..f40494446 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -61,8 +61,6 @@ struct d3d11_shader_runner ID3D11Texture2D *rt; ID3D11RenderTargetView *rtv; ID3D11DeviceContext *immediate_context; - - ID3D11VertexShader *vs; };
static struct d3d11_shader_runner *d3d11_shader_runner(struct shader_runner *r) @@ -74,11 +72,22 @@ static bool enable_debug_layer; static bool use_warp_adapter; static unsigned int use_adapter_idx;
-static ID3D10Blob *compile_shader(const char *source, const char *profile) +static ID3D10Blob *compile_shader(const char *source, const char *type, enum shader_model shader_model) { ID3D10Blob *blob = NULL, *errors = NULL; + char profile[7]; HRESULT hr;
+ static const char *const shader_models[] = + { + [SHADER_MODEL_2_0] = "4_0", + [SHADER_MODEL_4_0] = "4_0", + [SHADER_MODEL_4_1] = "4_1", + [SHADER_MODEL_5_0] = "5_0", + [SHADER_MODEL_5_1] = "5_1", + }; + + sprintf(profile, "%s_%s", type, shader_models[shader_model]); hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", profile, 0, 0, &blob, &errors); ok(hr == S_OK, "Failed to compile shader, hr %#lx.\n", hr); if (errors) @@ -323,9 +332,6 @@ static void destroy_test_context(struct d3d11_shader_runner *runner) { ULONG ref;
- if (runner->vs) - ID3D11VertexShader_Release(runner->vs); - ID3D11DeviceContext_Release(runner->immediate_context); ID3D11RenderTargetView_Release(runner->rtv); ID3D11Texture2D_Release(runner->rt); @@ -405,43 +411,28 @@ static void d3d11_runner_destroy_texture(struct shader_runner *r, struct texture
static void d3d11_runner_draw_quad(struct shader_runner *r) { - static const char vs_source[] = - "void main(uint id : SV_VertexID, out float4 position : SV_Position)\n" - "{\n" - " float2 coords = float2((id << 1) & 2, id & 2);\n" - " position = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1);\n" - "}"; - struct d3d11_shader_runner *runner = d3d11_shader_runner(r); ID3D11Device *device = runner->device; + ID3D10Blob *vs_code, *ps_code; ID3D11Buffer *cb = NULL; + ID3D11VertexShader *vs; ID3D11PixelShader *ps; - ID3D10Blob *ps_code; unsigned int i; HRESULT hr;
- static const char *const ps_profiles[] = - { - [SHADER_MODEL_2_0] = "ps_4_0", - [SHADER_MODEL_4_0] = "ps_4_0", - [SHADER_MODEL_4_1] = "ps_4_1", - [SHADER_MODEL_5_0] = "ps_5_0", - [SHADER_MODEL_5_1] = "ps_5_1", - }; - - if (!(ps_code = compile_shader(runner->r.ps_source, ps_profiles[runner->r.minimum_shader_model]))) + if (!(vs_code = compile_shader(runner->r.vs_source, "vs", runner->r.minimum_shader_model))) return;
- if (!runner->vs) + if (!(ps_code = compile_shader(runner->r.ps_source, "ps", runner->r.minimum_shader_model))) { - ID3D10Blob *vs_code = compile_shader(runner->r.vs_source ? runner->r.vs_source : vs_source, "vs_4_0"); - - hr = ID3D11Device_CreateVertexShader(device, ID3D10Blob_GetBufferPointer(vs_code), - ID3D10Blob_GetBufferSize(vs_code), NULL, &runner->vs); - ok(hr == S_OK, "Failed to create vertex shader, hr %#lx.\n", hr); ID3D10Blob_Release(vs_code); + return; }
+ hr = ID3D11Device_CreateVertexShader(device, ID3D10Blob_GetBufferPointer(vs_code), + ID3D10Blob_GetBufferSize(vs_code), NULL, &vs); + ok(hr == S_OK, "Failed to create vertex shader, hr %#lx.\n", hr); + hr = ID3D11Device_CreatePixelShader(device, ID3D10Blob_GetBufferPointer(ps_code), ID3D10Blob_GetBufferSize(ps_code), NULL, &ps); ok(hr == S_OK, "Failed to create pixel shader, hr %#lx.\n", hr); @@ -482,12 +473,13 @@ static void d3d11_runner_draw_quad(struct shader_runner *r) }
ID3D11DeviceContext_IASetPrimitiveTopology(runner->immediate_context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D11DeviceContext_VSSetShader(runner->immediate_context, runner->vs, NULL, 0); + ID3D11DeviceContext_VSSetShader(runner->immediate_context, vs, NULL, 0); ID3D11DeviceContext_PSSetShader(runner->immediate_context, ps, NULL, 0);
ID3D11DeviceContext_Draw(runner->immediate_context, 3, 0);
ID3D11PixelShader_Release(ps); + ID3D11VertexShader_Release(vs); if (cb) ID3D11Buffer_Release(cb); } diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index e124922fa..befa7f2f5 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -133,8 +133,8 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) ID3D12CommandQueue *queue = test_context->queue; D3D12_STATIC_SAMPLER_DESC static_samplers[1]; ID3D12Device *device = test_context->device; - ID3D10Blob *vs_code = NULL, *ps_code; static const float clear_color[4]; + ID3D10Blob *vs_code, *ps_code; D3D12_SHADER_BYTECODE vs, ps; unsigned int uniform_index; ID3D12PipelineState *pso; @@ -144,7 +144,7 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) if (!(ps_code = compile_shader(runner->r.ps_source, "ps", runner->r.minimum_shader_model))) return;
- if (runner->r.vs_source && !(vs_code = compile_shader(runner->r.vs_source, "vs", runner->r.minimum_shader_model))) + if (!(vs_code = compile_shader(runner->r.vs_source, "vs", runner->r.minimum_shader_model))) { ID3D10Blob_Release(ps_code); return; @@ -209,17 +209,13 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) hr = create_root_signature(device, &root_signature_desc, &test_context->root_signature); ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
- if (vs_code) - { - vs.pShaderBytecode = ID3D10Blob_GetBufferPointer(vs_code); - vs.BytecodeLength = ID3D10Blob_GetBufferSize(vs_code); - } + vs.pShaderBytecode = ID3D10Blob_GetBufferPointer(vs_code); + vs.BytecodeLength = ID3D10Blob_GetBufferSize(vs_code); ps.pShaderBytecode = ID3D10Blob_GetBufferPointer(ps_code); ps.BytecodeLength = ID3D10Blob_GetBufferSize(ps_code); pso = create_pipeline_state(device, test_context->root_signature, - test_context->render_target_desc.Format, vs_code ? &vs : NULL, &ps, NULL); - if (vs_code) - ID3D10Blob_Release(vs_code); + test_context->render_target_desc.Format, &vs, &ps, NULL); + ID3D10Blob_Release(vs_code); ID3D10Blob_Release(ps_code); if (!pso) return;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- tests/shader_runner.c | 63 ++++++++++++++++++++++++++++++++----- tests/shader_runner.h | 12 +++++++ tests/shader_runner_d3d11.c | 41 +++++++++++++++++++----- tests/shader_runner_d3d12.c | 23 +++++++++++++- 4 files changed, 124 insertions(+), 15 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index a2aecf9f9..383a61fb3 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -54,6 +54,7 @@ typedef int HRESULT; #include <errno.h> #include <stdbool.h> #include <stdio.h> +#include <string.h> #include "vkd3d_windows.h" #include "vkd3d_d3dcommon.h" #include "vkd3d_d3dcompiler.h" @@ -74,6 +75,7 @@ void fatal_error(const char *format, ...) enum parse_state { STATE_NONE, + STATE_INPUT_LAYOUT, STATE_PREPROC, STATE_PREPROC_INVALID, STATE_REQUIRE, @@ -89,6 +91,9 @@ static bool match_string(const char *line, const char *token, const char **const { size_t len = strlen(token);
+ while (isspace(*line)) + ++line; + if (strncmp(line, token, len) || !isspace(line[len])) return false; if (rest) @@ -131,7 +136,7 @@ static void parse_require_directive(struct shader_runner *runner, const char *li } }
-static void parse_texture_format(struct texture_params *texture, const char *line) +static DXGI_FORMAT parse_format(const char *line, enum texture_data_type *data_type, unsigned int *texel_size, const char **rest) { static const struct { @@ -151,12 +156,12 @@ static void parse_texture_format(struct texture_params *texture, const char *lin
for (i = 0; i < ARRAY_SIZE(formats); ++i) { - if (match_string(line, formats[i].string, &line)) + if (match_string(line, formats[i].string, rest)) { - texture->format = formats[i].format; - texture->data_type = formats[i].data_type; - texture->texel_size = formats[i].texel_size; - return; + if (data_type) + *data_type = formats[i].data_type; + *texel_size = formats[i].texel_size; + return formats[i].format; } }
@@ -230,7 +235,7 @@ static void parse_texture_directive(struct texture_params *texture, const char *
if (match_string(line, "format", &line)) { - parse_texture_format(texture, line); + texture->format = parse_format(line, &texture->data_type, &texture->texel_size, &line); } else if (match_string(line, "size", &line)) { @@ -278,6 +283,34 @@ static void parse_texture_directive(struct texture_params *texture, const char * } }
+static void parse_input_layout_directive(struct shader_runner *runner, const char *line) +{ + struct input_element *element; + const char *rest; + + vkd3d_array_reserve((void **)&runner->input_elements, &runner->input_element_capacity, + runner->input_element_count + 1, sizeof(*runner->input_elements)); + element = &runner->input_elements[runner->input_element_count++]; + + element->slot = strtoul(line, (char **)&rest, 10); + if (rest == line) + fatal_error("Malformed input layout directive '%s'.\n", line); + line = rest; + + element->format = parse_format(line, NULL, &element->texel_size, &line); + + if (!(rest = strpbrk(line, " \n"))) + rest = line + strlen(line); + element->name = malloc(rest - line + 1); + memcpy(element->name, line, rest - line); + element->name[rest - line] = 0; + line = rest; + + element->index = strtoul(line, (char **)&rest, 10); + if (rest == line) + element->index = 0; +} + static void set_uniforms(struct shader_runner *runner, size_t offset, size_t count, const void *uniforms) { runner->uniform_count = align(max(runner->uniform_count, offset + count), 4); @@ -493,6 +526,7 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const { switch (state) { + case STATE_INPUT_LAYOUT: case STATE_NONE: case STATE_REQUIRE: case STATE_SAMPLER: @@ -662,6 +696,14 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const { state = STATE_SHADER_VERTEX; } + else if (!strcmp(line, "[input layout]\n")) + { + state = STATE_INPUT_LAYOUT; + + for (i = 0; i < runner->input_element_count; ++i) + free(runner->input_elements[i].name); + runner->input_element_count = 0; + }
vkd3d_test_set_context("Section %.*s, line %u", strlen(line) - 1, line, line_number); } @@ -673,6 +715,10 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const fatal_error("Malformed line '%s'.\n", line); break;
+ case STATE_INPUT_LAYOUT: + parse_input_layout_directive(runner, line); + break; + case STATE_PREPROC: case STATE_PREPROC_INVALID: case STATE_SHADER_INVALID_PIXEL: @@ -706,6 +752,9 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const } }
+ for (i = 0; i < runner->input_element_count; ++i) + free(runner->input_elements[i].name); + free(runner->input_elements); free(runner->vs_source); free(runner->ps_source); for (i = 0; i < runner->texture_count; ++i) diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 43ded8534..8e2ca20e7 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -68,6 +68,15 @@ struct texture unsigned int slot; };
+struct input_element +{ + char *name; + unsigned int slot; + DXGI_FORMAT format; + unsigned int texel_size; + unsigned int index; +}; + struct shader_runner { const struct shader_runner_ops *ops; @@ -84,6 +93,9 @@ struct shader_runner
struct sampler *samplers; size_t sampler_count; + + struct input_element *input_elements; + size_t input_element_count, input_element_capacity; };
struct shader_runner_ops diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index f40494446..d419db2d8 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -412,6 +412,7 @@ static void d3d11_runner_destroy_texture(struct shader_runner *r, struct texture static void d3d11_runner_draw_quad(struct shader_runner *r) { struct d3d11_shader_runner *runner = d3d11_shader_runner(r); + ID3D11DeviceContext *context = runner->immediate_context; ID3D11Device *device = runner->device; ID3D10Blob *vs_code, *ps_code; ID3D11Buffer *cb = NULL; @@ -441,14 +442,14 @@ static void d3d11_runner_draw_quad(struct shader_runner *r) { cb = create_buffer(device, D3D11_BIND_CONSTANT_BUFFER, runner->r.uniform_count * sizeof(*runner->r.uniforms), runner->r.uniforms); - ID3D11DeviceContext_PSSetConstantBuffers(runner->immediate_context, 0, 1, &cb); + ID3D11DeviceContext_PSSetConstantBuffers(context, 0, 1, &cb); }
for (i = 0; i < runner->r.texture_count; ++i) { struct d3d11_texture *texture = d3d11_texture(runner->r.textures[i]);
- ID3D11DeviceContext_PSSetShaderResources(runner->immediate_context, texture->t.slot, 1, &texture->srv); + ID3D11DeviceContext_PSSetShaderResources(context, texture->t.slot, 1, &texture->srv); }
for (i = 0; i < runner->r.sampler_count; ++i) @@ -468,15 +469,41 @@ static void d3d11_runner_draw_quad(struct shader_runner *r)
hr = ID3D11Device_CreateSamplerState(device, &desc, &d3d11_sampler); ok(hr == S_OK, "Failed to create sampler state, hr %#lx.\n", hr); - ID3D11DeviceContext_PSSetSamplers(runner->immediate_context, sampler->slot, 1, &d3d11_sampler); + ID3D11DeviceContext_PSSetSamplers(context, sampler->slot, 1, &d3d11_sampler); ID3D11SamplerState_Release(d3d11_sampler); }
- ID3D11DeviceContext_IASetPrimitiveTopology(runner->immediate_context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D11DeviceContext_VSSetShader(runner->immediate_context, vs, NULL, 0); - ID3D11DeviceContext_PSSetShader(runner->immediate_context, ps, NULL, 0); + if (runner->r.input_element_count) + { + D3D11_INPUT_ELEMENT_DESC *descs; + ID3D11InputLayout *input_layout;
- ID3D11DeviceContext_Draw(runner->immediate_context, 3, 0); + descs = calloc(runner->r.input_element_count, sizeof(*descs)); + for (i = 0; i < runner->r.input_element_count; ++i) + { + const struct input_element *element = &runner->r.input_elements[i]; + D3D11_INPUT_ELEMENT_DESC *desc = &descs[i]; + + desc->SemanticName = element->name; + desc->SemanticIndex = element->index; + desc->Format = element->format; + desc->InputSlot = element->slot; + desc->AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; + desc->InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + } + + hr = ID3D11Device_CreateInputLayout(device, descs, runner->r.input_element_count, + ID3D10Blob_GetBufferPointer(vs_code), ID3D10Blob_GetBufferSize(vs_code), &input_layout); + ok(hr == S_OK, "Failed to create input layout, hr %#lx.\n", hr); + ID3D11DeviceContext_IASetInputLayout(context, input_layout); + ID3D11InputLayout_Release(input_layout); + } + + ID3D11DeviceContext_IASetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D11DeviceContext_VSSetShader(context, vs, NULL, 0); + ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0); + + ID3D11DeviceContext_Draw(context, 3, 0);
ID3D11PixelShader_Release(ps); ID3D11VertexShader_Release(vs); diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index befa7f2f5..e442d16e1 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -131,8 +131,10 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) D3D12_ROOT_SIGNATURE_DESC root_signature_desc = {0}; D3D12_ROOT_PARAMETER root_params[3], *root_param; ID3D12CommandQueue *queue = test_context->queue; + D3D12_INPUT_ELEMENT_DESC *input_element_descs; D3D12_STATIC_SAMPLER_DESC static_samplers[1]; ID3D12Device *device = test_context->device; + D3D12_INPUT_LAYOUT_DESC input_layout; static const float clear_color[4]; ID3D10Blob *vs_code, *ps_code; D3D12_SHADER_BYTECODE vs, ps; @@ -154,6 +156,7 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) root_signature_desc.pParameters = root_params; root_signature_desc.NumStaticSamplers = 0; root_signature_desc.pStaticSamplers = static_samplers; + root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
if (runner->r.uniform_count) { @@ -209,14 +212,32 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) hr = create_root_signature(device, &root_signature_desc, &test_context->root_signature); ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
+ input_element_descs = calloc(runner->r.input_element_count, sizeof(*input_element_descs)); + for (i = 0; i < runner->r.input_element_count; ++i) + { + const struct input_element *element = &runner->r.input_elements[i]; + D3D12_INPUT_ELEMENT_DESC *desc = &input_element_descs[i]; + + desc->SemanticName = element->name; + desc->SemanticIndex = element->index; + desc->Format = element->format; + desc->InputSlot = element->slot; + desc->AlignedByteOffset = D3D12_APPEND_ALIGNED_ELEMENT; + desc->InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; + } + + input_layout.pInputElementDescs = input_element_descs; + input_layout.NumElements = runner->r.input_element_count; + vs.pShaderBytecode = ID3D10Blob_GetBufferPointer(vs_code); vs.BytecodeLength = ID3D10Blob_GetBufferSize(vs_code); ps.pShaderBytecode = ID3D10Blob_GetBufferPointer(ps_code); ps.BytecodeLength = ID3D10Blob_GetBufferSize(ps_code); pso = create_pipeline_state(device, test_context->root_signature, - test_context->render_target_desc.Format, &vs, &ps, NULL); + test_context->render_target_desc.Format, &vs, &ps, &input_layout); ID3D10Blob_Release(vs_code); ID3D10Blob_Release(ps_code); + free(input_element_descs); if (!pso) return; vkd3d_array_reserve((void **)&test_context->pso, &test_context->pso_capacity,
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Use it to hold any type of resource, regardless of type and binding.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- tests/shader_runner.c | 55 +++++++++--------- tests/shader_runner.h | 19 ++++-- tests/shader_runner_d3d11.c | 85 +++++++++++++++------------ tests/shader_runner_d3d12.c | 113 ++++++++++++++++++++---------------- 4 files changed, 154 insertions(+), 118 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 383a61fb3..f203e4530 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -229,17 +229,17 @@ static void parse_sampler_directive(struct sampler *sampler, const char *line) } }
-static void parse_texture_directive(struct texture_params *texture, const char *line) +static void parse_resource_directive(struct resource_params *resource, const char *line) { int ret;
if (match_string(line, "format", &line)) { - texture->format = parse_format(line, &texture->data_type, &texture->texel_size, &line); + resource->format = parse_format(line, &resource->data_type, &resource->texel_size, &line); } else if (match_string(line, "size", &line)) { - ret = sscanf(line, "( %u , %u )", &texture->width, &texture->height); + ret = sscanf(line, "( %u , %u )", &resource->width, &resource->height); if (ret < 2) fatal_error("Malformed texture size '%s'.\n", line); } @@ -257,7 +257,7 @@ static void parse_texture_directive(struct texture_params *texture, const char *
for (;;) { - switch (texture->data_type) + switch (resource->data_type) { case TEXTURE_DATA_FLOAT: u.f = strtof(line, &rest); @@ -275,9 +275,9 @@ static void parse_texture_directive(struct texture_params *texture, const char * if (rest == line) break;
- vkd3d_array_reserve((void **)&texture->data, &texture->data_capacity, texture->data_size + sizeof(u), 1); - memcpy(texture->data + texture->data_size, &u, sizeof(u)); - texture->data_size += sizeof(u); + vkd3d_array_reserve((void **)&resource->data, &resource->data_capacity, resource->data_size + sizeof(u), 1); + memcpy(resource->data + resource->data_size, &u, sizeof(u)); + resource->data_size += sizeof(u); line = rest; } } @@ -460,29 +460,29 @@ static struct sampler *get_sampler(struct shader_runner *runner, unsigned int sl return NULL; }
-static void set_texture(struct shader_runner *runner, struct texture *texture) +static void set_resource(struct shader_runner *runner, struct resource *resource) { size_t i;
- for (i = 0; i < runner->texture_count; ++i) + for (i = 0; i < runner->resource_count; ++i) { - if (runner->textures[i]->slot == texture->slot) + if (runner->resources[i]->slot == resource->slot && runner->resources[i]->type == resource->type) { - runner->ops->destroy_texture(runner, runner->textures[i]); - runner->textures[i] = texture; + runner->ops->destroy_resource(runner, runner->resources[i]); + runner->resources[i] = resource; return; } }
- runner->textures = realloc(runner->textures, (runner->texture_count + 1) * sizeof(*runner->textures)); - runner->textures[runner->texture_count++] = texture; + runner->resources = realloc(runner->resources, (runner->resource_count + 1) * sizeof(*runner->resources)); + runner->resources[runner->resource_count++] = resource; }
void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const struct shader_runner_ops *ops) { size_t shader_source_size = 0, shader_source_len = 0; + struct resource_params current_resource; struct sampler *current_sampler = NULL; - struct texture_params current_texture; enum parse_state state = STATE_NONE; unsigned int i, line_number = 0; const char *filename = NULL; @@ -534,8 +534,8 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const break;
case STATE_TEXTURE: - set_texture(runner, runner->ops->create_texture(runner, ¤t_texture)); - free(current_texture.data); + set_resource(runner, runner->ops->create_resource(runner, ¤t_resource)); + free(current_resource.data); break;
case STATE_SHADER_PIXEL: @@ -673,12 +673,13 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const { state = STATE_TEXTURE;
- memset(¤t_texture, 0, sizeof(current_texture)); + memset(¤t_resource, 0, sizeof(current_resource));
- current_texture.slot = index; - current_texture.format = DXGI_FORMAT_R32G32B32A32_FLOAT; - current_texture.data_type = TEXTURE_DATA_FLOAT; - current_texture.texel_size = 16; + current_resource.slot = index; + current_resource.type = RESOURCE_TYPE_TEXTURE; + current_resource.format = DXGI_FORMAT_R32G32B32A32_FLOAT; + current_resource.data_type = TEXTURE_DATA_FLOAT; + current_resource.texel_size = 16; } else if (!strcmp(line, "[test]\n")) { @@ -742,7 +743,7 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const break;
case STATE_TEXTURE: - parse_texture_directive(¤t_texture, line); + parse_resource_directive(¤t_resource, line); break;
case STATE_TEST: @@ -757,12 +758,12 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const free(runner->input_elements); free(runner->vs_source); free(runner->ps_source); - for (i = 0; i < runner->texture_count; ++i) + for (i = 0; i < runner->resource_count; ++i) { - if (runner->textures[i]) - runner->ops->destroy_texture(runner, runner->textures[i]); + if (runner->resources[i]) + runner->ops->destroy_resource(runner, runner->resources[i]); } - free(runner->textures); + free(runner->resources);
fclose(f);
diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 8e2ca20e7..67944fda4 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -51,9 +51,15 @@ struct sampler D3D12_TEXTURE_ADDRESS_MODE u_address, v_address, w_address; };
-struct texture_params +enum resource_type +{ + RESOURCE_TYPE_TEXTURE, +}; + +struct resource_params { unsigned int slot; + enum resource_type type;
DXGI_FORMAT format; enum texture_data_type data_type; @@ -63,9 +69,10 @@ struct texture_params size_t data_size, data_capacity; };
-struct texture +struct resource { unsigned int slot; + enum resource_type type; };
struct input_element @@ -88,8 +95,8 @@ struct shader_runner uint32_t *uniforms; size_t uniform_count, uniform_capacity;
- struct texture **textures; - size_t texture_count; + struct resource **resources; + size_t resource_count;
struct sampler *samplers; size_t sampler_count; @@ -100,8 +107,8 @@ struct shader_runner
struct shader_runner_ops { - struct texture *(*create_texture)(struct shader_runner *runner, const struct texture_params *params); - void (*destroy_texture)(struct shader_runner *runner, struct texture *texture); + struct resource *(*create_resource)(struct shader_runner *runner, const struct resource_params *params); + void (*destroy_resource)(struct shader_runner *runner, struct resource *resource); void (*draw_quad)(struct shader_runner *runner); void (*probe_vec4)(struct shader_runner *runner, const RECT *rect, const struct vec4 *v, unsigned int ulps); }; diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index d419db2d8..838e04ff5 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -38,17 +38,17 @@ static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TY UINT sdk_version, ID3D11Device **device_out, D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context);
-struct d3d11_texture +struct d3d11_resource { - struct texture t; + struct resource r;
ID3D11Texture2D *texture; ID3D11ShaderResourceView *srv; };
-static struct d3d11_texture *d3d11_texture(struct texture *t) +static struct d3d11_resource *d3d11_resource(struct resource *r) { - return CONTAINING_RECORD(t, struct d3d11_texture, t); + return CONTAINING_RECORD(r, struct d3d11_resource, r); }
struct d3d11_shader_runner @@ -365,48 +365,56 @@ static ID3D11Buffer *create_buffer(ID3D11Device *device, unsigned int bind_flags return buffer; }
-static struct texture *d3d11_runner_create_texture(struct shader_runner *r, const struct texture_params *params) +static struct resource *d3d11_runner_create_resource(struct shader_runner *r, const struct resource_params *params) { struct d3d11_shader_runner *runner = d3d11_shader_runner(r); ID3D11Device *device = runner->device; D3D11_SUBRESOURCE_DATA resource_data; - D3D11_TEXTURE2D_DESC desc = {0}; - struct d3d11_texture *texture; + struct d3d11_resource *resource; HRESULT hr;
- texture = calloc(1, sizeof(*texture)); + resource = calloc(1, sizeof(*resource));
- texture->t.slot = params->slot; + resource->r.slot = params->slot; + resource->r.type = params->type;
- desc.Width = params->width; - desc.Height = params->height; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = params->format; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + switch (params->type) + { + case RESOURCE_TYPE_TEXTURE: + { + D3D11_TEXTURE2D_DESC desc = {0};
- resource_data.pSysMem = params->data; - resource_data.SysMemPitch = params->width * params->texel_size; - resource_data.SysMemSlicePitch = params->height * resource_data.SysMemPitch; + desc.Width = params->width; + desc.Height = params->height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = params->format; + desc.SampleDesc.Count = 1; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
- hr = ID3D11Device_CreateTexture2D(device, &desc, &resource_data, &texture->texture); - ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr); - hr = ID3D11Device_CreateShaderResourceView(device, - (ID3D11Resource *)texture->texture, NULL, &texture->srv); - ok(hr == S_OK, "Failed to create shader resource view, hr %#lx.\n", hr); + resource_data.pSysMem = params->data; + resource_data.SysMemPitch = params->width * params->texel_size; + resource_data.SysMemSlicePitch = params->height * resource_data.SysMemPitch;
- return &texture->t; + hr = ID3D11Device_CreateTexture2D(device, &desc, &resource_data, &resource->texture); + ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr); + hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)resource->texture, NULL, &resource->srv); + ok(hr == S_OK, "Failed to create shader resource view, hr %#lx.\n", hr); + break; + } + } + + return &resource->r; }
-static void d3d11_runner_destroy_texture(struct shader_runner *r, struct texture *t) +static void d3d11_runner_destroy_resource(struct shader_runner *r, struct resource *res) { - struct d3d11_texture *texture = d3d11_texture(t); + struct d3d11_resource *resource = d3d11_resource(res);
- ID3D11Texture2D_Release(texture->texture); - ID3D11ShaderResourceView_Release(texture->srv); - free(texture); + ID3D11Texture2D_Release(resource->texture); + ID3D11ShaderResourceView_Release(resource->srv); + free(resource); }
static void d3d11_runner_draw_quad(struct shader_runner *r) @@ -445,11 +453,16 @@ static void d3d11_runner_draw_quad(struct shader_runner *r) ID3D11DeviceContext_PSSetConstantBuffers(context, 0, 1, &cb); }
- for (i = 0; i < runner->r.texture_count; ++i) + for (i = 0; i < runner->r.resource_count; ++i) { - struct d3d11_texture *texture = d3d11_texture(runner->r.textures[i]); + struct d3d11_resource *resource = d3d11_resource(runner->r.resources[i]);
- ID3D11DeviceContext_PSSetShaderResources(context, texture->t.slot, 1, &texture->srv); + switch (resource->r.type) + { + case RESOURCE_TYPE_TEXTURE: + ID3D11DeviceContext_PSSetShaderResources(context, resource->r.slot, 1, &resource->srv); + break; + } }
for (i = 0; i < runner->r.sampler_count; ++i) @@ -583,8 +596,8 @@ static void d3d11_runner_probe_vec4(struct shader_runner *r, const RECT *rect, c
static const struct shader_runner_ops d3d11_runner_ops = { - .create_texture = d3d11_runner_create_texture, - .destroy_texture = d3d11_runner_destroy_texture, + .create_resource = d3d11_runner_create_resource, + .destroy_resource = d3d11_runner_destroy_resource, .draw_quad = d3d11_runner_draw_quad, .probe_vec4 = d3d11_runner_probe_vec4, }; diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index e442d16e1..1d38ee906 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -24,18 +24,18 @@ #include "d3d12_crosstest.h" #include "shader_runner.h"
-struct d3d12_texture +struct d3d12_resource { - struct texture t; + struct resource r;
D3D12_DESCRIPTOR_RANGE descriptor_range; ID3D12Resource *resource; unsigned int root_index; };
-static struct d3d12_texture *d3d12_texture(struct texture *t) +static struct d3d12_resource *d3d12_resource(struct resource *r) { - return CONTAINING_RECORD(t, struct d3d12_texture, t); + return CONTAINING_RECORD(r, struct d3d12_resource, r); }
struct d3d12_shader_runner @@ -81,45 +81,50 @@ static ID3D10Blob *compile_shader(const char *source, const char *type, enum sha
#define MAX_RESOURCE_DESCRIPTORS 256
-static struct texture *d3d12_runner_create_texture(struct shader_runner *r, const struct texture_params *params) +static struct resource *d3d12_runner_create_resource(struct shader_runner *r, const struct resource_params *params) { struct d3d12_shader_runner *runner = d3d12_shader_runner(r); struct test_context *test_context = &runner->test_context; ID3D12Device *device = test_context->device; D3D12_SUBRESOURCE_DATA resource_data; - struct d3d12_texture *texture; + struct d3d12_resource *resource;
- if (!runner->heap) - runner->heap = create_gpu_descriptor_heap(device, - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS); + resource = calloc(1, sizeof(*resource)); + resource->r.slot = params->slot; + resource->r.type = params->type;
- if (params->slot >= MAX_RESOURCE_DESCRIPTORS) - fatal_error("Resource slot %u is too high; please increase MAX_RESOURCE_DESCRIPTORS.\n", params->slot); + switch (params->type) + { + case RESOURCE_TYPE_TEXTURE: + if (!runner->heap) + runner->heap = create_gpu_descriptor_heap(device, + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, MAX_RESOURCE_DESCRIPTORS);
- texture = calloc(1, sizeof(*texture)); + if (params->slot >= MAX_RESOURCE_DESCRIPTORS) + fatal_error("Resource slot %u is too high; please increase MAX_RESOURCE_DESCRIPTORS.\n", params->slot);
- texture->t.slot = params->slot; + resource->resource = create_default_texture(device, params->width, params->height, + params->format, 0, D3D12_RESOURCE_STATE_COPY_DEST); + resource_data.pData = params->data; + resource_data.SlicePitch = resource_data.RowPitch = params->width * params->texel_size; + upload_texture_data(resource->resource, &resource_data, 1, test_context->queue, test_context->list); + reset_command_list(test_context->list, test_context->allocator); + transition_resource_state(test_context->list, resource->resource, D3D12_RESOURCE_STATE_COPY_DEST, + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + ID3D12Device_CreateShaderResourceView(device, resource->resource, + NULL, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot)); + break; + }
- texture->resource = create_default_texture(device, params->width, params->height, - params->format, 0, D3D12_RESOURCE_STATE_COPY_DEST); - resource_data.pData = params->data; - resource_data.SlicePitch = resource_data.RowPitch = params->width * params->texel_size; - upload_texture_data(texture->resource, &resource_data, 1, test_context->queue, test_context->list); - reset_command_list(test_context->list, test_context->allocator); - transition_resource_state(test_context->list, texture->resource, D3D12_RESOURCE_STATE_COPY_DEST, - D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); - ID3D12Device_CreateShaderResourceView(device, texture->resource, - NULL, get_cpu_descriptor_handle(test_context, runner->heap, params->slot)); - - return &texture->t; + return &resource->r; }
-static void d3d12_runner_destroy_texture(struct shader_runner *r, struct texture *t) +static void d3d12_runner_destroy_resource(struct shader_runner *r, struct resource *res) { - struct d3d12_texture *texture = d3d12_texture(t); + struct d3d12_resource *resource = d3d12_resource(res);
- ID3D12Resource_Release(texture->resource); - free(texture); + ID3D12Resource_Release(resource->resource); + free(resource); }
static void d3d12_runner_draw_quad(struct shader_runner *r) @@ -169,25 +174,30 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) root_param->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; }
- for (i = 0; i < runner->r.texture_count; ++i) + for (i = 0; i < runner->r.resource_count; ++i) { - struct d3d12_texture *texture = d3d12_texture(runner->r.textures[i]); + struct d3d12_resource *resource = d3d12_resource(runner->r.resources[i]); D3D12_DESCRIPTOR_RANGE *range;
- range = &texture->descriptor_range; + switch (resource->r.type) + { + case RESOURCE_TYPE_TEXTURE: + range = &resource->descriptor_range;
- texture->root_index = root_signature_desc.NumParameters++; - root_param = &root_params[texture->root_index]; - root_param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; - root_param->DescriptorTable.NumDescriptorRanges = 1; - root_param->DescriptorTable.pDescriptorRanges = range; - root_param->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + resource->root_index = root_signature_desc.NumParameters++; + root_param = &root_params[resource->root_index]; + root_param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + root_param->DescriptorTable.NumDescriptorRanges = 1; + root_param->DescriptorTable.pDescriptorRanges = range; + root_param->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; - range->NumDescriptors = 1; - range->BaseShaderRegister = texture->t.slot; - range->RegisterSpace = 0; - range->OffsetInDescriptorsFromTableStart = 0; + range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + range->NumDescriptors = 1; + range->BaseShaderRegister = resource->r.slot; + range->RegisterSpace = 0; + range->OffsetInDescriptorsFromTableStart = 0; + break; + } }
assert(root_signature_desc.NumParameters <= ARRAY_SIZE(root_params)); @@ -248,12 +258,17 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) if (runner->r.uniform_count) ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, uniform_index, runner->r.uniform_count, runner->r.uniforms, 0); - for (i = 0; i < runner->r.texture_count; ++i) + for (i = 0; i < runner->r.resource_count; ++i) { - struct d3d12_texture *texture = d3d12_texture(runner->r.textures[i]); + struct d3d12_resource *resource = d3d12_resource(runner->r.resources[i]);
- ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, texture->root_index, - get_gpu_descriptor_handle(test_context, runner->heap, texture->t.slot)); + switch (resource->r.type) + { + case RESOURCE_TYPE_TEXTURE: + ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, resource->root_index, + get_gpu_descriptor_handle(test_context, runner->heap, resource->r.slot)); + break; + } }
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &test_context->rtv, false, NULL); @@ -290,8 +305,8 @@ static void d3d12_runner_probe_vec4(struct shader_runner *r,
static const struct shader_runner_ops d3d12_runner_ops = { - .create_texture = d3d12_runner_create_texture, - .destroy_texture = d3d12_runner_destroy_texture, + .create_resource = d3d12_runner_create_resource, + .destroy_resource = d3d12_runner_destroy_resource, .draw_quad = d3d12_runner_draw_quad, .probe_vec4 = d3d12_runner_probe_vec4, };
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- tests/shader_runner.c | 31 +++++++++++++++++++++++++++++++ tests/shader_runner.h | 5 +++++ tests/shader_runner_d3d11.c | 23 ++++++++++++++++++----- tests/shader_runner_d3d12.c | 17 +++++++++++++++++ 4 files changed, 71 insertions(+), 5 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index f203e4530..b564a8a59 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -85,6 +85,7 @@ enum parse_state STATE_SHADER_VERTEX, STATE_TEXTURE, STATE_TEST, + STATE_VERTEX_BUFFER, };
static bool match_string(const char *line, const char *token, const char **const rest) @@ -478,6 +479,24 @@ static void set_resource(struct shader_runner *runner, struct resource *resource runner->resources[runner->resource_count++] = resource; }
+unsigned int get_vb_stride(const struct shader_runner *runner, unsigned int slot) +{ + unsigned int stride = 0; + size_t i; + + /* We currently don't deal with vertex formats less than 32 bits, so don't + * bother with alignment. */ + for (i = 0; i < runner->input_element_count; ++i) + { + const struct input_element *element = &runner->input_elements[i]; + + if (element->slot == slot) + stride += element->texel_size; + } + + return stride; +} + void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const struct shader_runner_ops *ops) { size_t shader_source_size = 0, shader_source_len = 0; @@ -534,6 +553,7 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const break;
case STATE_TEXTURE: + case STATE_VERTEX_BUFFER: set_resource(runner, runner->ops->create_resource(runner, ¤t_resource)); free(current_resource.data); break; @@ -681,6 +701,16 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const current_resource.data_type = TEXTURE_DATA_FLOAT; current_resource.texel_size = 16; } + else if (sscanf(line, "[vertex buffer %u]\n", &index)) + { + state = STATE_VERTEX_BUFFER; + + memset(¤t_resource, 0, sizeof(current_resource)); + + current_resource.slot = index; + current_resource.type = RESOURCE_TYPE_VERTEX_BUFFER; + current_resource.data_type = TEXTURE_DATA_FLOAT; + } else if (!strcmp(line, "[test]\n")) { state = STATE_TEST; @@ -743,6 +773,7 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const break;
case STATE_TEXTURE: + case STATE_VERTEX_BUFFER: parse_resource_directive(¤t_resource, line); break;
diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 67944fda4..dd692b5c6 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -54,6 +54,7 @@ struct sampler enum resource_type { RESOURCE_TYPE_TEXTURE, + RESOURCE_TYPE_VERTEX_BUFFER, };
struct resource_params @@ -73,6 +74,8 @@ struct resource { unsigned int slot; enum resource_type type; + + unsigned int size; };
struct input_element @@ -115,6 +118,8 @@ struct shader_runner_ops
void fatal_error(const char *format, ...) VKD3D_NORETURN VKD3D_PRINTF_FUNC(1, 2);
+unsigned int get_vb_stride(const struct shader_runner *runner, unsigned int slot); + void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const struct shader_runner_ops *ops);
#ifdef _WIN32 diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index 838e04ff5..5b20d22d8 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -42,7 +42,7 @@ struct d3d11_resource { struct resource r;
- ID3D11Texture2D *texture; + ID3D11Resource *resource; ID3D11ShaderResourceView *srv; };
@@ -397,12 +397,17 @@ static struct resource *d3d11_runner_create_resource(struct shader_runner *r, co resource_data.SysMemPitch = params->width * params->texel_size; resource_data.SysMemSlicePitch = params->height * resource_data.SysMemPitch;
- hr = ID3D11Device_CreateTexture2D(device, &desc, &resource_data, &resource->texture); + hr = ID3D11Device_CreateTexture2D(device, &desc, &resource_data, (ID3D11Texture2D **)&resource->resource); ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr); - hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)resource->texture, NULL, &resource->srv); + hr = ID3D11Device_CreateShaderResourceView(device, resource->resource, NULL, &resource->srv); ok(hr == S_OK, "Failed to create shader resource view, hr %#lx.\n", hr); break; } + + case RESOURCE_TYPE_VERTEX_BUFFER: + resource->resource = (ID3D11Resource *)create_buffer(device, + D3D11_BIND_VERTEX_BUFFER, params->data_size, params->data); + break; }
return &resource->r; @@ -412,8 +417,9 @@ static void d3d11_runner_destroy_resource(struct shader_runner *r, struct resour { struct d3d11_resource *resource = d3d11_resource(res);
- ID3D11Texture2D_Release(resource->texture); - ID3D11ShaderResourceView_Release(resource->srv); + ID3D11Resource_Release(resource->resource); + if (resource->srv) + ID3D11ShaderResourceView_Release(resource->srv); free(resource); }
@@ -456,12 +462,19 @@ static void d3d11_runner_draw_quad(struct shader_runner *r) for (i = 0; i < runner->r.resource_count; ++i) { struct d3d11_resource *resource = d3d11_resource(runner->r.resources[i]); + unsigned int stride = get_vb_stride(&runner->r, resource->r.slot); + unsigned int offset = 0;
switch (resource->r.type) { case RESOURCE_TYPE_TEXTURE: ID3D11DeviceContext_PSSetShaderResources(context, resource->r.slot, 1, &resource->srv); break; + + case RESOURCE_TYPE_VERTEX_BUFFER: + ID3D11DeviceContext_IASetVertexBuffers(context, resource->r.slot, 1, + (ID3D11Buffer **)&resource->resource, &stride, &offset); + break; } }
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 1d38ee906..588964b5b 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -92,6 +92,7 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co resource = calloc(1, sizeof(*resource)); resource->r.slot = params->slot; resource->r.type = params->type; + resource->r.size = params->data_size;
switch (params->type) { @@ -114,6 +115,10 @@ static struct resource *d3d12_runner_create_resource(struct shader_runner *r, co ID3D12Device_CreateShaderResourceView(device, resource->resource, NULL, get_cpu_descriptor_handle(test_context, runner->heap, resource->r.slot)); break; + + case RESOURCE_TYPE_VERTEX_BUFFER: + resource->resource = create_upload_buffer(device, params->data_size, params->data); + break; }
return &resource->r; @@ -197,6 +202,9 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) range->RegisterSpace = 0; range->OffsetInDescriptorsFromTableStart = 0; break; + + case RESOURCE_TYPE_VERTEX_BUFFER: + break; } }
@@ -261,6 +269,7 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) for (i = 0; i < runner->r.resource_count; ++i) { struct d3d12_resource *resource = d3d12_resource(runner->r.resources[i]); + D3D12_VERTEX_BUFFER_VIEW vbv;
switch (resource->r.type) { @@ -268,6 +277,14 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, resource->root_index, get_gpu_descriptor_handle(test_context, runner->heap, resource->r.slot)); break; + + case RESOURCE_TYPE_VERTEX_BUFFER: + vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(resource->resource); + vbv.StrideInBytes = get_vb_stride(&runner->r, resource->r.slot); + vbv.SizeInBytes = resource->r.size; + + ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, resource->r.slot, 1, &vbv); + break; } }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- tests/shader_runner.c | 2 +- tests/shader_runner.h | 2 +- tests/shader_runner_d3d11.c | 6 +++--- tests/shader_runner_d3d12.c | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index b564a8a59..04819c7d3 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -334,7 +334,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) if (!runner->vs_source) runner->vs_source = strdup(vs_source);
- runner->ops->draw_quad(runner); + runner->ops->draw(runner, 3); } else if (match_string(line, "probe all rgba", &line)) { diff --git a/tests/shader_runner.h b/tests/shader_runner.h index dd692b5c6..7e29873c4 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -112,7 +112,7 @@ 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 (*draw_quad)(struct shader_runner *runner); + void (*draw)(struct shader_runner *runner, unsigned int vertex_count); void (*probe_vec4)(struct shader_runner *runner, const RECT *rect, const struct vec4 *v, unsigned int ulps); };
diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index 5b20d22d8..f2181ffc0 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -423,7 +423,7 @@ static void d3d11_runner_destroy_resource(struct shader_runner *r, struct resour free(resource); }
-static void d3d11_runner_draw_quad(struct shader_runner *r) +static void d3d11_runner_draw(struct shader_runner *r, unsigned int vertex_count) { struct d3d11_shader_runner *runner = d3d11_shader_runner(r); ID3D11DeviceContext *context = runner->immediate_context; @@ -529,7 +529,7 @@ static void d3d11_runner_draw_quad(struct shader_runner *r) ID3D11DeviceContext_VSSetShader(context, vs, NULL, 0); ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0);
- ID3D11DeviceContext_Draw(context, 3, 0); + ID3D11DeviceContext_Draw(context, vertex_count, 0);
ID3D11PixelShader_Release(ps); ID3D11VertexShader_Release(vs); @@ -611,7 +611,7 @@ static const struct shader_runner_ops d3d11_runner_ops = { .create_resource = d3d11_runner_create_resource, .destroy_resource = d3d11_runner_destroy_resource, - .draw_quad = d3d11_runner_draw_quad, + .draw = d3d11_runner_draw, .probe_vec4 = d3d11_runner_probe_vec4, };
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 588964b5b..2dda6a75b 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -132,7 +132,7 @@ static void d3d12_runner_destroy_resource(struct shader_runner *r, struct resour free(resource); }
-static void d3d12_runner_draw_quad(struct shader_runner *r) +static void d3d12_runner_draw(struct shader_runner *r, unsigned int vertex_count) { struct d3d12_shader_runner *runner = d3d12_shader_runner(r); struct test_context *test_context = &runner->test_context; @@ -294,7 +294,7 @@ static void d3d12_runner_draw_quad(struct shader_runner *r) ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, test_context->rtv, clear_color, 0, NULL); ID3D12GraphicsCommandList_SetPipelineState(command_list, pso); - ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0); + ID3D12GraphicsCommandList_DrawInstanced(command_list, vertex_count, 1, 0, 0); transition_resource_state(command_list, test_context->render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
@@ -324,7 +324,7 @@ static const struct shader_runner_ops d3d12_runner_ops = { .create_resource = d3d12_runner_create_resource, .destroy_resource = d3d12_runner_destroy_resource, - .draw_quad = d3d12_runner_draw_quad, + .draw = d3d12_runner_draw, .probe_vec4 = d3d12_runner_probe_vec4, };
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- tests/shader_runner.c | 2 +- tests/shader_runner.h | 2 +- tests/shader_runner_d3d11.c | 5 +++-- tests/shader_runner_d3d12.c | 5 +++-- 4 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 04819c7d3..c3f967a2e 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -334,7 +334,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) if (!runner->vs_source) runner->vs_source = strdup(vs_source);
- runner->ops->draw(runner, 3); + runner->ops->draw(runner, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, 3); } else if (match_string(line, "probe all rgba", &line)) { diff --git a/tests/shader_runner.h b/tests/shader_runner.h index 7e29873c4..a98917c5f 100644 --- a/tests/shader_runner.h +++ b/tests/shader_runner.h @@ -112,7 +112,7 @@ 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 (*draw)(struct shader_runner *runner, unsigned int vertex_count); + void (*draw)(struct shader_runner *runner, D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count); void (*probe_vec4)(struct shader_runner *runner, const RECT *rect, const struct vec4 *v, unsigned int ulps); };
diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c index f2181ffc0..93904a648 100644 --- a/tests/shader_runner_d3d11.c +++ b/tests/shader_runner_d3d11.c @@ -423,7 +423,8 @@ static void d3d11_runner_destroy_resource(struct shader_runner *r, struct resour free(resource); }
-static void d3d11_runner_draw(struct shader_runner *r, unsigned int vertex_count) +static void d3d11_runner_draw(struct shader_runner *r, + D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count) { struct d3d11_shader_runner *runner = d3d11_shader_runner(r); ID3D11DeviceContext *context = runner->immediate_context; @@ -525,7 +526,7 @@ static void d3d11_runner_draw(struct shader_runner *r, unsigned int vertex_count ID3D11InputLayout_Release(input_layout); }
- ID3D11DeviceContext_IASetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D11DeviceContext_IASetPrimitiveTopology(context, primitive_topology); ID3D11DeviceContext_VSSetShader(context, vs, NULL, 0); ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0);
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 2dda6a75b..06221691e 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -132,7 +132,8 @@ static void d3d12_runner_destroy_resource(struct shader_runner *r, struct resour free(resource); }
-static void d3d12_runner_draw(struct shader_runner *r, unsigned int vertex_count) +static void d3d12_runner_draw(struct shader_runner *r, + D3D_PRIMITIVE_TOPOLOGY primitive_topology, unsigned int vertex_count) { struct d3d12_shader_runner *runner = d3d12_shader_runner(r); struct test_context *test_context = &runner->test_context; @@ -291,7 +292,7 @@ static void d3d12_runner_draw(struct shader_runner *r, unsigned int vertex_count ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &test_context->rtv, false, NULL); ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &test_context->scissor_rect); ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &test_context->viewport); - ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, primitive_topology); ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, test_context->rtv, clear_color, 0, NULL); ID3D12GraphicsCommandList_SetPipelineState(command_list, pso); ID3D12GraphicsCommandList_DrawInstanced(command_list, vertex_count, 1, 0, 0);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- Makefile.am | 2 ++ tests/nointerpolation.shader_test | 27 +++++++++++++++++++++++++++ tests/shader_runner.c | 17 +++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 tests/nointerpolation.shader_test
diff --git a/Makefile.am b/Makefile.am index f2c8440c7..64cfe5342 100644 --- a/Makefile.am +++ b/Makefile.am @@ -103,6 +103,7 @@ vkd3d_shader_tests = \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/logic-operations.shader_test \ tests/math.shader_test \ + tests/nointerpolation.shader_test \ tests/pow.shader_test \ tests/preproc-if.shader_test \ tests/preproc-ifdef.shader_test \ @@ -351,6 +352,7 @@ XFAIL_TESTS = \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/logic-operations.shader_test \ tests/max.shader_test \ + tests/nointerpolation.shader_test \ tests/sampler-offset.shader_test \ tests/trigonometry.shader_test endif diff --git a/tests/nointerpolation.shader_test b/tests/nointerpolation.shader_test new file mode 100644 index 000000000..8f15be6ed --- /dev/null +++ b/tests/nointerpolation.shader_test @@ -0,0 +1,27 @@ +[require] +shader model >= 4.0 + +[input layout] +0 r32g32b32a32 float texcoord + +[vertex buffer 0] +0.0 1.0 0.0 1.0 +1.0 0.0 0.0 1.0 +0.0 0.0 1.0 1.0 + +[vertex shader] +void main(uint id : sv_vertexid, nointerpolation inout float4 t : texcoord, out float4 pos : sv_position) +{ + float2 coords = float2((id << 1) & 2, id & 2); + pos = float4(coords * float2(2, -2) + float2(-1, 1), 0, 1); +} + +[pixel shader] +float4 main(nointerpolation float4 t : texcoord) : sv_target +{ + return t; +} + +[test] +draw triangle list 3 +probe all rgba (0.0, 1.0, 0.0, 1.0) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index c3f967a2e..99f2a22f8 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -336,6 +336,23 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
runner->ops->draw(runner, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, 3); } + else if (match_string(line, "draw", &line)) + { + D3D_PRIMITIVE_TOPOLOGY topology; + unsigned int vertex_count; + char *rest; + + if (match_string(line, "triangle list", &line)) + topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + else + fatal_error("Unknown primitive topology '%s'.\n", line); + + vertex_count = strtoul(line, &rest, 10); + if (line == rest) + fatal_error("Malformed vertex count '%s'.\n", line); + + runner->ops->draw(runner, topology, vertex_count); + } else if (match_string(line, "probe all rgba", &line)) { static const RECT rect = {0, 0, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT};
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com