[PATCH vkd3d 4/5] tests: Add a test for texture load instructions.

Giovanni Mascellani gmascellani at codeweavers.com
Mon Oct 4 09:55:07 CDT 2021


Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>
---
I basically learned how to create and upload textures in D3D12 reading 
this patch, so it's not really an independent review. However reading 
the code and the docs aside seemed to make sense, so I think I can sign 
off on it.

Il 04/10/21 02:19, Zebediah Figura ha scritto:
> Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
> ---
>   Makefile.am                    |   2 +
>   tests/d3d12.c                  |  89 -----------------
>   tests/d3d12_test_utils.h       |  89 +++++++++++++++++
>   tests/shader_runner_d3d12.c    | 175 ++++++++++++++++++++++++++++++++-
>   tests/texture-load.shader_test |  19 ++++
>   5 files changed, 281 insertions(+), 93 deletions(-)
>   create mode 100644 tests/texture-load.shader_test
> 
> diff --git a/Makefile.am b/Makefile.am
> index bc33e0f60..921bb7964 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -99,6 +99,7 @@ vkd3d_shader_tests = \
>   	tests/swizzle-5.shader_test \
>   	tests/swizzle-6.shader_test \
>   	tests/swizzle-7.shader_test \
> +	tests/texture-load.shader_test \
>   	tests/trigonometry.shader_test \
>   	tests/writemask-assignop-0.shader_test \
>   	tests/writemask-assignop-1.shader_test \
> @@ -299,6 +300,7 @@ XFAIL_TESTS = \
>   	tests/hlsl-vector-indexing-uniform.shader_test \
>   	tests/math.shader_test \
>   	tests/max.shader_test \
> +	tests/texture-load.shader_test \
>   	tests/trigonometry.shader_test \
>   	tests/writemask-assignop-1.shader_test
>   endif
> diff --git a/tests/d3d12.c b/tests/d3d12.c
> index b4c136137..3ef93e911 100644
> --- a/tests/d3d12.c
> +++ b/tests/d3d12.c
> @@ -155,22 +155,6 @@ static void uav_barrier(ID3D12GraphicsCommandList *list, ID3D12Resource *resourc
>       ID3D12GraphicsCommandList_ResourceBarrier(list, 1, &barrier);
>   }
>   
> -static void copy_sub_resource_data(const D3D12_MEMCPY_DEST *dst, const D3D12_SUBRESOURCE_DATA *src,
> -        unsigned int row_count, unsigned int slice_count, size_t row_size)
> -{
> -    const BYTE *src_slice_ptr;
> -    BYTE *dst_slice_ptr;
> -    unsigned int z, y;
> -
> -    for (z = 0; z < slice_count; ++z)
> -    {
> -        dst_slice_ptr = (BYTE *)dst->pData + z * dst->SlicePitch;
> -        src_slice_ptr = (const BYTE*)src->pData + z * src->SlicePitch;
> -        for (y = 0; y < row_count; ++y)
> -            memcpy(dst_slice_ptr + y * dst->RowPitch, src_slice_ptr + y * src->RowPitch, row_size);
> -    }
> -}
> -
>   #define upload_buffer_data(a, b, c, d, e, f) upload_buffer_data_(__LINE__, a, b, c, d, e, f)
>   static void upload_buffer_data_(unsigned int line, ID3D12Resource *buffer, size_t offset,
>           size_t size, const void *data, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list)
> @@ -196,79 +180,6 @@ static void upload_buffer_data_(unsigned int line, ID3D12Resource *buffer, size_
>       ID3D12Device_Release(device);
>   }
>   
> -#define upload_texture_data(a, b, c, d, e) upload_texture_data_(__LINE__, a, b, c, d, e)
> -static void upload_texture_data_(unsigned int line, ID3D12Resource *texture,
> -        const D3D12_SUBRESOURCE_DATA *data, unsigned int sub_resource_count,
> -        ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list)
> -{
> -    D3D12_TEXTURE_COPY_LOCATION dst_location, src_location;
> -    D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts;
> -    uint64_t *row_sizes, required_size;
> -    D3D12_RESOURCE_DESC resource_desc;
> -    ID3D12Resource *upload_buffer;
> -    D3D12_MEMCPY_DEST dst_data;
> -    ID3D12Device *device;
> -    UINT *row_counts;
> -    unsigned int i;
> -    HRESULT hr;
> -    void *ptr;
> -
> -    layouts = calloc(sub_resource_count, sizeof(*layouts));
> -    ok(layouts, "Failed to allocate memory.\n");
> -    row_counts = calloc(sub_resource_count, sizeof(*row_counts));
> -    ok(row_counts, "Failed to allocate memory.\n");
> -    row_sizes = calloc(sub_resource_count, sizeof(*row_sizes));
> -    ok(row_sizes, "Failed to allocate memory.\n");
> -
> -    resource_desc = ID3D12Resource_GetDesc(texture);
> -    hr = ID3D12Resource_GetDevice(texture, &IID_ID3D12Device, (void **)&device);
> -    ok_(line)(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
> -
> -    ID3D12Device_GetCopyableFootprints(device, &resource_desc, 0, sub_resource_count,
> -            0, layouts, row_counts, row_sizes, &required_size);
> -
> -    upload_buffer = create_upload_buffer_(line, device, required_size, NULL);
> -
> -    hr = ID3D12Resource_Map(upload_buffer, 0, NULL, (void **)&ptr);
> -    ok_(line)(SUCCEEDED(hr), "Failed to map upload buffer, hr %#x.\n", hr);
> -    for (i = 0; i < sub_resource_count; ++i)
> -    {
> -        dst_data.pData = (BYTE *)ptr + layouts[i].Offset;
> -        dst_data.RowPitch = layouts[i].Footprint.RowPitch;
> -        dst_data.SlicePitch = layouts[i].Footprint.RowPitch * row_counts[i];
> -        copy_sub_resource_data(&dst_data, &data[i],
> -                row_counts[i], layouts[i].Footprint.Depth, row_sizes[i]);
> -    }
> -    ID3D12Resource_Unmap(upload_buffer, 0, NULL);
> -
> -    for (i = 0; i < sub_resource_count; ++i)
> -    {
> -        dst_location.pResource = texture;
> -        dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
> -        dst_location.SubresourceIndex = i;
> -
> -        src_location.pResource = upload_buffer;
> -        src_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
> -        src_location.PlacedFootprint = layouts[i];
> -
> -        ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
> -                &dst_location, 0, 0, 0, &src_location, NULL);
> -    }
> -
> -    hr = ID3D12GraphicsCommandList_Close(command_list);
> -    ok_(line)(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
> -
> -    exec_command_list(queue, command_list);
> -    wait_queue_idle(device, queue);
> -
> -    ID3D12Resource_Release(upload_buffer);
> -    ID3D12Device_Release(device);
> -
> -    free(layouts);
> -    free(row_counts);
> -    free(row_sizes);
> -}
> -
>   static const DXGI_FORMAT depth_stencil_formats[] =
>   {
>       DXGI_FORMAT_R32G8X24_TYPELESS,
> diff --git a/tests/d3d12_test_utils.h b/tests/d3d12_test_utils.h
> index 0374d8d11..5d900f891 100644
> --- a/tests/d3d12_test_utils.h
> +++ b/tests/d3d12_test_utils.h
> @@ -697,6 +697,95 @@ static inline ID3D12Resource *create_default_texture3d_(unsigned int line, ID3D1
>               width, height, depth, miplevel_count, format, flags, initial_state);
>   }
>   
> +static void copy_sub_resource_data(const D3D12_MEMCPY_DEST *dst, const D3D12_SUBRESOURCE_DATA *src,
> +        unsigned int row_count, unsigned int slice_count, size_t row_size)
> +{
> +    const BYTE *src_slice_ptr;
> +    BYTE *dst_slice_ptr;
> +    unsigned int z, y;
> +
> +    for (z = 0; z < slice_count; ++z)
> +    {
> +        dst_slice_ptr = (BYTE *)dst->pData + z * dst->SlicePitch;
> +        src_slice_ptr = (const BYTE*)src->pData + z * src->SlicePitch;
> +        for (y = 0; y < row_count; ++y)
> +            memcpy(dst_slice_ptr + y * dst->RowPitch, src_slice_ptr + y * src->RowPitch, row_size);
> +    }
> +}
> +
> +#define upload_texture_data(a, b, c, d, e) upload_texture_data_(__LINE__, a, b, c, d, e)
> +static inline void upload_texture_data_(unsigned int line, ID3D12Resource *texture,
> +        const D3D12_SUBRESOURCE_DATA *data, unsigned int sub_resource_count,
> +        ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list)
> +{
> +    D3D12_TEXTURE_COPY_LOCATION dst_location, src_location;
> +    D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts;
> +    uint64_t *row_sizes, required_size;
> +    D3D12_RESOURCE_DESC resource_desc;
> +    ID3D12Resource *upload_buffer;
> +    D3D12_MEMCPY_DEST dst_data;
> +    ID3D12Device *device;
> +    UINT *row_counts;
> +    unsigned int i;
> +    HRESULT hr;
> +    void *ptr;
> +
> +    layouts = calloc(sub_resource_count, sizeof(*layouts));
> +    ok(layouts, "Failed to allocate memory.\n");
> +    row_counts = calloc(sub_resource_count, sizeof(*row_counts));
> +    ok(row_counts, "Failed to allocate memory.\n");
> +    row_sizes = calloc(sub_resource_count, sizeof(*row_sizes));
> +    ok(row_sizes, "Failed to allocate memory.\n");
> +
> +    resource_desc = ID3D12Resource_GetDesc(texture);
> +    hr = ID3D12Resource_GetDevice(texture, &IID_ID3D12Device, (void **)&device);
> +    ok_(line)(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
> +
> +    ID3D12Device_GetCopyableFootprints(device, &resource_desc, 0, sub_resource_count,
> +            0, layouts, row_counts, row_sizes, &required_size);
> +
> +    upload_buffer = create_upload_buffer_(line, device, required_size, NULL);
> +
> +    hr = ID3D12Resource_Map(upload_buffer, 0, NULL, (void **)&ptr);
> +    ok_(line)(SUCCEEDED(hr), "Failed to map upload buffer, hr %#x.\n", hr);
> +    for (i = 0; i < sub_resource_count; ++i)
> +    {
> +        dst_data.pData = (BYTE *)ptr + layouts[i].Offset;
> +        dst_data.RowPitch = layouts[i].Footprint.RowPitch;
> +        dst_data.SlicePitch = layouts[i].Footprint.RowPitch * row_counts[i];
> +        copy_sub_resource_data(&dst_data, &data[i],
> +                row_counts[i], layouts[i].Footprint.Depth, row_sizes[i]);
> +    }
> +    ID3D12Resource_Unmap(upload_buffer, 0, NULL);
> +
> +    for (i = 0; i < sub_resource_count; ++i)
> +    {
> +        dst_location.pResource = texture;
> +        dst_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
> +        dst_location.SubresourceIndex = i;
> +
> +        src_location.pResource = upload_buffer;
> +        src_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
> +        src_location.PlacedFootprint = layouts[i];
> +
> +        ID3D12GraphicsCommandList_CopyTextureRegion(command_list,
> +                &dst_location, 0, 0, 0, &src_location, NULL);
> +    }
> +
> +    hr = ID3D12GraphicsCommandList_Close(command_list);
> +    ok_(line)(SUCCEEDED(hr), "Failed to close command list, hr %#x.\n", hr);
> +
> +    exec_command_list(queue, command_list);
> +    wait_queue_idle(device, queue);
> +
> +    ID3D12Resource_Release(upload_buffer);
> +    ID3D12Device_Release(device);
> +
> +    free(layouts);
> +    free(row_counts);
> +    free(row_sizes);
> +}
> +
>   static HRESULT create_root_signature(ID3D12Device *device, const D3D12_ROOT_SIGNATURE_DESC *desc,
>           ID3D12RootSignature **root_signature)
>   {
> diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c
> index a0cdc5b38..171a855f1 100644
> --- a/tests/shader_runner_d3d12.c
> +++ b/tests/shader_runner_d3d12.c
> @@ -73,6 +73,20 @@ static bool vkd3d_array_reserve(void **elements, size_t *capacity, size_t elemen
>       return true;
>   }
>   
> +struct texture
> +{
> +    unsigned int slot;
> +
> +    unsigned int width, height;
> +    uint8_t *data;
> +    size_t data_size, data_capacity;
> +
> +    D3D12_DESCRIPTOR_RANGE descriptor_range;
> +    ID3D12DescriptorHeap *heap;
> +    ID3D12Resource *resource;
> +    unsigned int root_index;
> +};
> +
>   struct shader_context
>   {
>       struct test_context c;
> @@ -81,6 +95,9 @@ struct shader_context
>   
>       uint32_t *uniforms;
>       size_t uniform_count;
> +
> +    struct texture *textures;
> +    size_t texture_count;
>   };
>   
>   static ID3D10Blob *compile_shader(const char *source, const char *target)
> @@ -99,6 +116,14 @@ static ID3D10Blob *compile_shader(const char *source, const char *target)
>       return blob;
>   }
>   
> +static void free_texture(struct texture *texture)
> +{
> +    ID3D12DescriptorHeap_Release(texture->heap);
> +    ID3D12Resource_Release(texture->resource);
> +    free(texture->data);
> +    memset(texture, 0, sizeof(*texture));
> +}
> +
>   enum parse_state
>   {
>       STATE_NONE,
> @@ -106,6 +131,7 @@ enum parse_state
>       STATE_PREPROC_INVALID,
>       STATE_SHADER_INVALID_PIXEL,
>       STATE_SHADER_PIXEL,
> +    STATE_TEXTURE,
>       STATE_TEST,
>   };
>   
> @@ -124,6 +150,37 @@ static bool match_string(const char *line, const char *token, const char **const
>       return true;
>   }
>   
> +static void parse_texture_directive(struct texture *texture, const char *line)
> +{
> +    const char *const orig_line = line;
> +    int ret;
> +
> +    if (match_string(line, "size", &line))
> +    {
> +        ret = sscanf(line, "( %u , %u )", &texture->width, &texture->height);
> +        if (ret < 2)
> +            goto err;
> +    }
> +    else
> +    {
> +        char *rest;
> +        float f;
> +
> +        while ((f = strtof(line, &rest)) || rest != line)
> +        {
> +            vkd3d_array_reserve((void **)&texture->data, &texture->data_capacity, texture->data_size + sizeof(f), 1);
> +            memcpy(texture->data + texture->data_size, &f, sizeof(f));
> +            texture->data_size += sizeof(f);
> +            line = rest;
> +        }
> +    }
> +
> +    return;
> +
> +err:
> +    fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line);
> +}
> +
>   static void parse_test_directive(struct shader_context *context, const char *line)
>   {
>       const char *const orig_line = line;
> @@ -133,13 +190,66 @@ static void parse_test_directive(struct shader_context *context, const char *lin
>           D3D12_SHADER_BYTECODE ps
>                   = {ID3D10Blob_GetBufferPointer(context->ps_code), ID3D10Blob_GetBufferSize(context->ps_code)};
>           ID3D12GraphicsCommandList *command_list = context->c.list;
> +        D3D12_ROOT_SIGNATURE_DESC root_signature_desc = {0};
> +        D3D12_ROOT_PARAMETER root_params[2], *root_param;
>           static const float clear_color[4];
> +        unsigned int uniform_index;
>           ID3D12PipelineState *pso;
> +        HRESULT hr;
> +        size_t i;
> +
> +        root_signature_desc.NumParameters = 0;
> +        root_signature_desc.pParameters = root_params;
> +
> +        if (context->uniform_count)
> +        {
> +            uniform_index = root_signature_desc.NumParameters++;
> +            root_param = &root_params[uniform_index];
> +            root_param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
> +            root_param->Constants.ShaderRegister = 0;
> +            root_param->Constants.RegisterSpace = 0;
> +            root_param->Constants.Num32BitValues = context->uniform_count;
> +            root_param->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
> +        }
> +
> +        for (i = 0; i < context->texture_count; ++i)
> +        {
> +            struct texture *texture = &context->textures[i];
> +            D3D12_DESCRIPTOR_RANGE *range = &texture->descriptor_range;
> +            D3D12_SUBRESOURCE_DATA resource_data;
> +
> +            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;
> +
> +            range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
> +            range->NumDescriptors = 1;
> +            range->BaseShaderRegister = texture->slot;
> +            range->RegisterSpace = 0;
> +            range->OffsetInDescriptorsFromTableStart = 0;
> +
> +            texture->heap = create_gpu_descriptor_heap(context->c.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
> +            texture->resource = create_default_texture(context->c.device, texture->width, texture->height,
> +                    DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
> +            resource_data.pData = texture->data;
> +            resource_data.SlicePitch = resource_data.RowPitch = texture->width * sizeof(struct vec4);
> +            upload_texture_data(texture->resource, &resource_data, 1, context->c.queue, command_list);
> +            reset_command_list(command_list, context->c.allocator);
> +            transition_resource_state(command_list, texture->resource, D3D12_RESOURCE_STATE_COPY_DEST,
> +                    D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
> +            ID3D12Device_CreateShaderResourceView(context->c.device, texture->resource,
> +                    NULL, get_cpu_descriptor_handle(&context->c, texture->heap, 0));
> +        }
> +
> +        assert(root_signature_desc.NumParameters <= ARRAY_SIZE(root_params));
>   
>           if (context->c.root_signature)
>               ID3D12RootSignature_Release(context->c.root_signature);
> -        context->c.root_signature = create_32bit_constants_root_signature(context->c.device,
> -                0, context->uniform_count, D3D12_SHADER_VISIBILITY_ALL);
> +        hr = create_root_signature(context->c.device, &root_signature_desc, &context->c.root_signature);
> +        ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
>   
>           pso = create_pipeline_state(context->c.device, context->c.root_signature,
>                   context->c.render_target_desc.Format, NULL, &ps, NULL);
> @@ -147,8 +257,13 @@ static void parse_test_directive(struct shader_context *context, const char *lin
>               return;
>   
>           ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context->c.root_signature);
> -        ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0,
> -                context->uniform_count, context->uniforms, 0);
> +        if (context->uniform_count)
> +            ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, uniform_index,
> +                    context->uniform_count, context->uniforms, 0);
> +        for (i = 0; i < context->texture_count; ++i)
> +            ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, context->textures[i].root_index,
> +                    get_gpu_descriptor_handle(&context->c, context->textures[i].heap, 0));
> +
>           ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context->c.rtv, false, NULL);
>           ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context->c.scissor_rect);
>           ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context->c.viewport);
> @@ -293,6 +408,21 @@ err:
>       fprintf(stderr, "Ignoring malformed line '%s'.\n", orig_line);
>   }
>   
> +static struct texture *get_texture(struct shader_context *context, unsigned int slot)
> +{
> +    struct texture *texture;
> +    size_t i;
> +
> +    for (i = 0; i < context->texture_count; ++i)
> +    {
> +        texture = &context->textures[i];
> +        if (texture->slot == slot)
> +            return texture;
> +    }
> +
> +    return NULL;
> +}
> +
>   START_TEST(shader_runner_d3d12)
>   {
>       static const struct test_context_desc desc =
> @@ -305,6 +435,7 @@ START_TEST(shader_runner_d3d12)
>       size_t shader_source_size = 0, shader_source_len = 0;
>       enum parse_state state = STATE_NONE;
>       unsigned int i, line_number = 0;
> +    struct texture *current_texture;
>       struct shader_context context;
>       const char *filename = NULL;
>       char *shader_source = NULL;
> @@ -351,6 +482,7 @@ START_TEST(shader_runner_d3d12)
>               {
>                   case STATE_NONE:
>                   case STATE_TEST:
> +                case STATE_TEXTURE:
>                       break;
>   
>                   case STATE_SHADER_PIXEL:
> @@ -439,16 +571,45 @@ START_TEST(shader_runner_d3d12)
>   
>           if (line[0] == '[')
>           {
> +            unsigned int index;
> +
>               if (!strcmp(line, "[pixel shader]\n"))
> +            {
>                   state = STATE_SHADER_PIXEL;
> +            }
>               else if (!strcmp(line, "[pixel shader fail]\n"))
> +            {
>                   state = STATE_SHADER_INVALID_PIXEL;
> +            }
> +            else if (sscanf(line, "[texture %u]\n", &index))
> +            {
> +                state = STATE_TEXTURE;
> +
> +                if ((current_texture = get_texture(&context, index)))
> +                {
> +                    free_texture(current_texture);
> +                }
> +                else
> +                {
> +                    context.textures = realloc(context.textures,
> +                            ++context.texture_count * sizeof(*context.textures));
> +                    current_texture = &context.textures[context.texture_count - 1];
> +                    memset(current_texture, 0, sizeof(*current_texture));
> +                }
> +                current_texture->slot = index;
> +            }
>               else if (!strcmp(line, "[test]\n"))
> +            {
>                   state = STATE_TEST;
> +            }
>               else if (!strcmp(line, "[preproc]\n"))
> +            {
>                   state = STATE_PREPROC;
> +            }
>               else if (!strcmp(line, "[preproc fail]\n"))
> +            {
>                   state = STATE_PREPROC_INVALID;
> +            }
>   
>               vkd3d_test_set_context("Section %.*s, line %u", strlen(line) - 1, line, line_number);
>           }
> @@ -473,6 +634,10 @@ START_TEST(shader_runner_d3d12)
>                       break;
>                   }
>   
> +                case STATE_TEXTURE:
> +                    parse_texture_directive(current_texture, line);
> +                    break;
> +
>                   case STATE_TEST:
>                       parse_test_directive(&context, line);
>                       break;
> @@ -482,6 +647,8 @@ START_TEST(shader_runner_d3d12)
>   
>       if (context.ps_code)
>           ID3D10Blob_Release(context.ps_code);
> +    for (i = 0; i < context.texture_count; ++i)
> +        free_texture(&context.textures[i]);
>       destroy_test_context(&context.c);
>   
>       fclose(f);
> diff --git a/tests/texture-load.shader_test b/tests/texture-load.shader_test
> new file mode 100644
> index 000000000..86b36af49
> --- /dev/null
> +++ b/tests/texture-load.shader_test
> @@ -0,0 +1,19 @@
> +[texture 0]
> +size (2, 2)
> +0.1 0.2 0.3 0.4     0.5 0.7 0.6 0.8
> +0.6 0.5 0.2 0.1     0.8 0.0 0.7 1.0
> +
> +[pixel shader]
> +Texture2D t;
> +
> +float4 main(float4 pos : sv_position) : sv_target
> +{
> +    return t.Load(int3(pos.xy, 0));
> +}
> +
> +[test]
> +draw quad
> +probe rgba (0, 0) (0.1, 0.2, 0.3, 0.4)
> +probe rgba (1, 0) (0.5, 0.7, 0.6, 0.8)
> +probe rgba (0, 1) (0.6, 0.5, 0.2, 0.1)
> +probe rgba (1, 1) (0.8, 0.0, 0.7, 1.0)
> 



More information about the wine-devel mailing list