[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