[PATCH vkd3d v3 05/14] tests: Add a shader test for texture sampling.
Giovanni Mascellani
gmascellani at codeweavers.com
Mon Nov 8 02:29:17 CST 2021
Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>
On 05/11/21 19:35, Matteo Bruni wrote:
> From: Zebediah Figura <zfigura at codeweavers.com>
>
> Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
> Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
> ---
> v3: Add validation of filter directive, initialize current_sampler variable.
>
> Makefile.am | 2 +
> tests/sampler.shader_test | 34 +++++++++
> tests/shader_runner_d3d12.c | 141 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 177 insertions(+)
> create mode 100644 tests/sampler.shader_test
>
> diff --git a/Makefile.am b/Makefile.am
> index eaa4f816..d6e14cf1 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -90,6 +90,7 @@ vkd3d_shader_tests = \
> tests/preproc-invalid.shader_test \
> tests/preproc-macro.shader_test \
> tests/preproc-misc.shader_test \
> + tests/sampler.shader_test \
> tests/saturate.shader_test \
> tests/swizzle-0.shader_test \
> tests/swizzle-1.shader_test \
> @@ -302,6 +303,7 @@ XFAIL_TESTS = \
> tests/hlsl-vector-indexing-uniform.shader_test \
> tests/math.shader_test \
> tests/max.shader_test \
> + tests/sampler.shader_test \
> tests/texture-load.shader_test \
> tests/texture-load-typed.shader_test \
> tests/trigonometry.shader_test \
> diff --git a/tests/sampler.shader_test b/tests/sampler.shader_test
> new file mode 100644
> index 00000000..3970fb51
> --- /dev/null
> +++ b/tests/sampler.shader_test
> @@ -0,0 +1,34 @@
> +[sampler 0]
> +filter linear linear linear
> +address clamp clamp clamp
> +
> +[texture 0]
> +size (2, 2)
> +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
> +0.0 0.0 0.0 0.0 1.0 0.0 1.0 0.0
> +
> +[pixel shader]
> +sampler s;
> +Texture2D t;
> +
> +float4 main() : sv_target
> +{
> + return t.Sample(s, float2(0.5, 0.5));
> +}
> +
> +[test]
> +draw quad
> +probe all rgba (0.25, 0, 0.25, 0)
> +
> +[pixel shader]
> +SamplerState s;
> +Texture2D t;
> +
> +float4 main() : sv_target
> +{
> + return t.Sample(s, float2(0.5, 0.5));
> +}
> +
> +[test]
> +draw quad
> +probe all rgba (0.25, 0, 0.25, 0)
> diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c
> index 20d1ad6a..8dd95dce 100644
> --- a/tests/shader_runner_d3d12.c
> +++ b/tests/shader_runner_d3d12.c
> @@ -80,6 +80,14 @@ enum texture_data_type
> TEXTURE_DATA_UINT,
> };
>
> +struct sampler
> +{
> + unsigned int slot;
> +
> + D3D12_FILTER filter;
> + D3D12_TEXTURE_ADDRESS_MODE u_address, v_address, w_address;
> +};
> +
> struct texture
> {
> unsigned int slot;
> @@ -108,6 +116,9 @@ struct shader_context
>
> struct texture *textures;
> size_t texture_count;
> +
> + struct sampler *samplers;
> + size_t sampler_count;
> };
>
> static ID3D10Blob *compile_shader(const char *source, const char *target)
> @@ -139,6 +150,7 @@ enum parse_state
> STATE_NONE,
> STATE_PREPROC,
> STATE_PREPROC_INVALID,
> + STATE_SAMPLER,
> STATE_SHADER_INVALID_PIXEL,
> STATE_SHADER_PIXEL,
> STATE_TEXTURE,
> @@ -195,6 +207,74 @@ static void parse_texture_format(struct texture *texture, const char *line)
> texture->texel_size = 16;
> }
>
> +static D3D12_TEXTURE_ADDRESS_MODE parse_sampler_address_mode(const char *line, const char **rest)
> +{
> + if (match_string(line, "border", rest))
> + return D3D12_TEXTURE_ADDRESS_MODE_BORDER;
> + if (match_string(line, "clamp", rest))
> + return D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
> + if (match_string(line, "mirror_once", rest))
> + return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE;
> + if (match_string(line, "mirror", rest))
> + return D3D12_TEXTURE_ADDRESS_MODE_MIRROR;
> + if (match_string(line, "wrap", rest))
> + return D3D12_TEXTURE_ADDRESS_MODE_WRAP;
> + fprintf(stderr, "Malformed address mode '%s'.\n", line);
> + return D3D12_TEXTURE_ADDRESS_MODE_WRAP;
> +}
> +
> +static void parse_sampler_directive(struct sampler *sampler, const char *line)
> +{
> + const char *const orig_line = line;
> +
> + if (match_string(line, "address", &line))
> + {
> + sampler->u_address = parse_sampler_address_mode(line, &line);
> + sampler->v_address = parse_sampler_address_mode(line, &line);
> + sampler->w_address = parse_sampler_address_mode(line, &line);
> + }
> + else if (match_string(line, "filter", &line))
> + {
> + static const struct
> + {
> + const char *string;
> + D3D12_FILTER filter;
> + }
> + filters[] =
> + {
> + {"point point point", D3D12_FILTER_MIN_MAG_MIP_POINT},
> + {"point point linear", D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR},
> + {"point linear point", D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT},
> + {"point linear linear", D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR},
> + {"linear point point", D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT},
> + {"linear point linear", D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR},
> + {"linear linear point", D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT},
> + {"linear linear linear", D3D12_FILTER_MIN_MAG_MIP_LINEAR},
> + };
> + unsigned int i;
> +
> + for (i = 0; i < ARRAY_SIZE(filters); ++i)
> + {
> + if (match_string(line, filters[i].string, &line))
> + {
> + sampler->filter = filters[i].filter;
> + break;
> + }
> + }
> + if (i == ARRAY_SIZE(filters))
> + goto err;
> + }
> + else
> + {
> + goto err;
> + }
> +
> + return;
> +
> +err:
> + fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line);
> +}
> +
> static void parse_texture_directive(struct texture *texture, const char *line)
> {
> const char *const orig_line = line;
> @@ -266,6 +346,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin
> ID3D12GraphicsCommandList *command_list = context->c.list;
> D3D12_ROOT_SIGNATURE_DESC root_signature_desc = {0};
> D3D12_ROOT_PARAMETER root_params[3], *root_param;
> + D3D12_STATIC_SAMPLER_DESC static_samplers[1];
> static const float clear_color[4];
> unsigned int uniform_index;
> ID3D12PipelineState *pso;
> @@ -274,6 +355,8 @@ static void parse_test_directive(struct shader_context *context, const char *lin
>
> root_signature_desc.NumParameters = 0;
> root_signature_desc.pParameters = root_params;
> + root_signature_desc.NumStaticSamplers = 0;
> + root_signature_desc.pStaticSamplers = static_samplers;
>
> if (context->uniform_count)
> {
> @@ -324,6 +407,21 @@ static void parse_test_directive(struct shader_context *context, const char *lin
>
> assert(root_signature_desc.NumParameters <= ARRAY_SIZE(root_params));
>
> + for (i = 0; i < context->sampler_count; ++i)
> + {
> + D3D12_STATIC_SAMPLER_DESC *sampler_desc = &static_samplers[root_signature_desc.NumStaticSamplers++];
> + const struct sampler *sampler = &context->samplers[i];
> +
> + memset(sampler_desc, 0, sizeof(*sampler_desc));
> + sampler_desc->Filter = sampler->filter;
> + sampler_desc->AddressU = sampler->u_address;
> + sampler_desc->AddressV = sampler->v_address;
> + sampler_desc->AddressW = sampler->w_address;
> + sampler_desc->ShaderRegister = sampler->slot;
> + sampler_desc->RegisterSpace = 0;
> + sampler_desc->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
> + }
> +
> if (context->c.root_signature)
> ID3D12RootSignature_Release(context->c.root_signature);
> hr = create_root_signature(context->c.device, &root_signature_desc, &context->c.root_signature);
> @@ -486,6 +584,22 @@ err:
> fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line);
> }
>
> +static struct sampler *get_sampler(struct shader_context *context, unsigned int slot)
> +{
> + struct sampler *sampler;
> + size_t i;
> +
> + for (i = 0; i < context->sampler_count; ++i)
> + {
> + sampler = &context->samplers[i];
> +
> + if (sampler->slot == slot)
> + return sampler;
> + }
> +
> + return NULL;
> +}
> +
> static struct texture *get_texture(struct shader_context *context, unsigned int slot)
> {
> struct texture *texture;
> @@ -511,6 +625,7 @@ START_TEST(shader_runner_d3d12)
> .rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT,
> };
> size_t shader_source_size = 0, shader_source_len = 0;
> + struct sampler *current_sampler = NULL;
> struct texture *current_texture = NULL;
> enum parse_state state = STATE_NONE;
> unsigned int i, line_number = 0;
> @@ -559,6 +674,7 @@ START_TEST(shader_runner_d3d12)
> switch (state)
> {
> case STATE_NONE:
> + case STATE_SAMPLER:
> case STATE_TEST:
> case STATE_TEXTURE:
> break;
> @@ -663,6 +779,27 @@ START_TEST(shader_runner_d3d12)
> {
> state = STATE_SHADER_INVALID_PIXEL;
> }
> + else if (sscanf(line, "[sampler %u]\n", &index))
> + {
> + state = STATE_SAMPLER;
> +
> + if ((current_sampler = get_sampler(&context, index)))
> + {
> + memset(current_sampler, 0, sizeof(*current_sampler));
> + }
> + else
> + {
> + context.samplers = realloc(context.samplers,
> + ++context.sampler_count * sizeof(*context.samplers));
> + current_sampler = &context.samplers[context.sampler_count - 1];
> + memset(current_sampler, 0, sizeof(*current_sampler));
> + }
> + current_sampler->slot = index;
> + current_sampler->filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
> + current_sampler->u_address = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
> + current_sampler->v_address = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
> + current_sampler->w_address = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
> + }
> else if (sscanf(line, "[texture %u]\n", &index))
> {
> state = STATE_TEXTURE;
> @@ -719,6 +856,10 @@ START_TEST(shader_runner_d3d12)
> break;
> }
>
> + case STATE_SAMPLER:
> + parse_sampler_directive(current_sampler, line);
> + break;
> +
> case STATE_TEXTURE:
> parse_texture_directive(current_texture, line);
> break;
>
More information about the wine-devel
mailing list