tests: Allow specifying a custom input layout.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2022-03-21 20:42:16 -05:00 committed by Alexandre Julliard
parent 16b383aef5
commit 3ed4c6fe23
4 changed files with 124 additions and 15 deletions

View File

@ -54,6 +54,7 @@ typedef int HRESULT;
#include <errno.h> #include <errno.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "vkd3d_windows.h" #include "vkd3d_windows.h"
#include "vkd3d_d3dcommon.h" #include "vkd3d_d3dcommon.h"
#include "vkd3d_d3dcompiler.h" #include "vkd3d_d3dcompiler.h"
@ -74,6 +75,7 @@ void fatal_error(const char *format, ...)
enum parse_state enum parse_state
{ {
STATE_NONE, STATE_NONE,
STATE_INPUT_LAYOUT,
STATE_PREPROC, STATE_PREPROC,
STATE_PREPROC_INVALID, STATE_PREPROC_INVALID,
STATE_REQUIRE, STATE_REQUIRE,
@ -89,6 +91,9 @@ static bool match_string(const char *line, const char *token, const char **const
{ {
size_t len = strlen(token); size_t len = strlen(token);
while (isspace(*line))
++line;
if (strncmp(line, token, len) || !isspace(line[len])) if (strncmp(line, token, len) || !isspace(line[len]))
return false; return false;
if (rest) 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 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) 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; if (data_type)
texture->data_type = formats[i].data_type; *data_type = formats[i].data_type;
texture->texel_size = formats[i].texel_size; *texel_size = formats[i].texel_size;
return; 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)) 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)) 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) 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); 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) switch (state)
{ {
case STATE_INPUT_LAYOUT:
case STATE_NONE: case STATE_NONE:
case STATE_REQUIRE: case STATE_REQUIRE:
case STATE_SAMPLER: case STATE_SAMPLER:
@ -662,6 +696,14 @@ void run_shader_tests(struct shader_runner *runner, int argc, char **argv, const
{ {
state = STATE_SHADER_VERTEX; 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); 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); fatal_error("Malformed line '%s'.\n", line);
break; break;
case STATE_INPUT_LAYOUT:
parse_input_layout_directive(runner, line);
break;
case STATE_PREPROC: case STATE_PREPROC:
case STATE_PREPROC_INVALID: case STATE_PREPROC_INVALID:
case STATE_SHADER_INVALID_PIXEL: 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->vs_source);
free(runner->ps_source); free(runner->ps_source);
for (i = 0; i < runner->texture_count; ++i) for (i = 0; i < runner->texture_count; ++i)

View File

@ -68,6 +68,15 @@ struct texture
unsigned int slot; unsigned int slot;
}; };
struct input_element
{
char *name;
unsigned int slot;
DXGI_FORMAT format;
unsigned int texel_size;
unsigned int index;
};
struct shader_runner struct shader_runner
{ {
const struct shader_runner_ops *ops; const struct shader_runner_ops *ops;
@ -84,6 +93,9 @@ struct shader_runner
struct sampler *samplers; struct sampler *samplers;
size_t sampler_count; size_t sampler_count;
struct input_element *input_elements;
size_t input_element_count, input_element_capacity;
}; };
struct shader_runner_ops struct shader_runner_ops

View File

@ -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) static void d3d11_runner_draw_quad(struct shader_runner *r)
{ {
struct d3d11_shader_runner *runner = d3d11_shader_runner(r); struct d3d11_shader_runner *runner = d3d11_shader_runner(r);
ID3D11DeviceContext *context = runner->immediate_context;
ID3D11Device *device = runner->device; ID3D11Device *device = runner->device;
ID3D10Blob *vs_code, *ps_code; ID3D10Blob *vs_code, *ps_code;
ID3D11Buffer *cb = NULL; 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, cb = create_buffer(device, D3D11_BIND_CONSTANT_BUFFER,
runner->r.uniform_count * sizeof(*runner->r.uniforms), runner->r.uniforms); 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) for (i = 0; i < runner->r.texture_count; ++i)
{ {
struct d3d11_texture *texture = d3d11_texture(runner->r.textures[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) 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); hr = ID3D11Device_CreateSamplerState(device, &desc, &d3d11_sampler);
ok(hr == S_OK, "Failed to create sampler state, hr %#lx.\n", hr); 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); ID3D11SamplerState_Release(d3d11_sampler);
} }
ID3D11DeviceContext_IASetPrimitiveTopology(runner->immediate_context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); if (runner->r.input_element_count)
ID3D11DeviceContext_VSSetShader(runner->immediate_context, vs, NULL, 0); {
ID3D11DeviceContext_PSSetShader(runner->immediate_context, ps, NULL, 0); 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); ID3D11PixelShader_Release(ps);
ID3D11VertexShader_Release(vs); ID3D11VertexShader_Release(vs);

View File

@ -131,8 +131,10 @@ static void d3d12_runner_draw_quad(struct shader_runner *r)
D3D12_ROOT_SIGNATURE_DESC root_signature_desc = {0}; D3D12_ROOT_SIGNATURE_DESC root_signature_desc = {0};
D3D12_ROOT_PARAMETER root_params[3], *root_param; D3D12_ROOT_PARAMETER root_params[3], *root_param;
ID3D12CommandQueue *queue = test_context->queue; ID3D12CommandQueue *queue = test_context->queue;
D3D12_INPUT_ELEMENT_DESC *input_element_descs;
D3D12_STATIC_SAMPLER_DESC static_samplers[1]; D3D12_STATIC_SAMPLER_DESC static_samplers[1];
ID3D12Device *device = test_context->device; ID3D12Device *device = test_context->device;
D3D12_INPUT_LAYOUT_DESC input_layout;
static const float clear_color[4]; static const float clear_color[4];
ID3D10Blob *vs_code, *ps_code; ID3D10Blob *vs_code, *ps_code;
D3D12_SHADER_BYTECODE vs, ps; 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.pParameters = root_params;
root_signature_desc.NumStaticSamplers = 0; root_signature_desc.NumStaticSamplers = 0;
root_signature_desc.pStaticSamplers = static_samplers; root_signature_desc.pStaticSamplers = static_samplers;
root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
if (runner->r.uniform_count) 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); 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); 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.pShaderBytecode = ID3D10Blob_GetBufferPointer(vs_code);
vs.BytecodeLength = ID3D10Blob_GetBufferSize(vs_code); vs.BytecodeLength = ID3D10Blob_GetBufferSize(vs_code);
ps.pShaderBytecode = ID3D10Blob_GetBufferPointer(ps_code); ps.pShaderBytecode = ID3D10Blob_GetBufferPointer(ps_code);
ps.BytecodeLength = ID3D10Blob_GetBufferSize(ps_code); ps.BytecodeLength = ID3D10Blob_GetBufferSize(ps_code);
pso = create_pipeline_state(device, test_context->root_signature, 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(vs_code);
ID3D10Blob_Release(ps_code); ID3D10Blob_Release(ps_code);
free(input_element_descs);
if (!pso) if (!pso)
return; return;
vkd3d_array_reserve((void **)&test_context->pso, &test_context->pso_capacity, vkd3d_array_reserve((void **)&test_context->pso, &test_context->pso_capacity,