[PATCH vkd3d v4 5/5] vkd3d-shader/hlsl: Parse the Load() method.

Giovanni Mascellani gmascellani at codeweavers.com
Fri Oct 8 03:42:51 CDT 2021


Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>

Il 08/10/21 04:58, Zebediah Figura ha scritto:
> Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
> ---
> v4: Pass a pointer to struct vkd3d_shader_location.
> 
>   libs/vkd3d-shader/hlsl.c         |  48 ++++++++++++++-
>   libs/vkd3d-shader/hlsl.h         |  26 +++++++-
>   libs/vkd3d-shader/hlsl.y         | 102 ++++++++++++++++++++++++++++++-
>   libs/vkd3d-shader/hlsl_codegen.c |  14 +++++
>   libs/vkd3d-shader/hlsl_sm1.c     |   5 ++
>   libs/vkd3d-shader/hlsl_sm4.c     |   5 ++
>   6 files changed, 196 insertions(+), 4 deletions(-)
> 
> diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
> index e0f26c0fe..9bce6bebe 100644
> --- a/libs/vkd3d-shader/hlsl.c
> +++ b/libs/vkd3d-shader/hlsl.c
> @@ -478,7 +478,7 @@ bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type)
>   }
>   
>   struct hlsl_ir_expr *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_type *type,
> -        struct vkd3d_shader_location *loc)
> +        const struct vkd3d_shader_location *loc)
>   {
>       struct hlsl_ir_node *cast;
>   
> @@ -626,6 +626,22 @@ struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var
>       return hlsl_new_load(ctx, var, NULL, var->data_type, loc);
>   }
>   
> +struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type,
> +        enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *offset,
> +        struct hlsl_ir_node *coords, const struct vkd3d_shader_location *loc)
> +{
> +    struct hlsl_ir_resource_load *load;
> +
> +    if (!(load = hlsl_alloc(ctx, sizeof(*load))))
> +        return NULL;
> +    init_node(&load->node, HLSL_IR_RESOURCE_LOAD, data_type, *loc);
> +    load->load_type = type;
> +    load->resource.var = resource;
> +    hlsl_src_from_node(&load->resource.offset, offset);
> +    hlsl_src_from_node(&load->coords, coords);
> +    return load;
> +}
> +
>   struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components,
>           struct hlsl_ir_node *val, struct vkd3d_shader_location *loc)
>   {
> @@ -994,6 +1010,7 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type)
>           "HLSL_IR_LOAD",
>           "HLSL_IR_LOOP",
>           "HLSL_IR_JUMP",
> +        "HLSL_IR_RESOURCE_LOAD",
>           "HLSL_IR_STORE",
>           "HLSL_IR_SWIZZLE",
>       };
> @@ -1216,6 +1233,20 @@ static void dump_ir_loop(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffe
>       vkd3d_string_buffer_printf(buffer, "}\n");
>   }
>   
> +static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_load *load)
> +{
> +    static const char *const type_names[] =
> +    {
> +        [HLSL_RESOURCE_LOAD] = "load_resource",
> +    };
> +
> +    vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]);
> +    dump_deref(buffer, &load->resource);
> +    vkd3d_string_buffer_printf(buffer, ", coords = ");
> +    dump_src(buffer, &load->coords);
> +    vkd3d_string_buffer_printf(buffer, ")");
> +}
> +
>   static void dump_ir_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_store *store)
>   {
>       vkd3d_string_buffer_printf(buffer, "= (");
> @@ -1282,6 +1313,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
>               dump_ir_loop(ctx, buffer, hlsl_ir_loop(instr));
>               break;
>   
> +        case HLSL_IR_RESOURCE_LOAD:
> +            dump_ir_resource_load(buffer, hlsl_ir_resource_load(instr));
> +            break;
> +
>           case HLSL_IR_STORE:
>               dump_ir_store(buffer, hlsl_ir_store(instr));
>               break;
> @@ -1380,6 +1415,13 @@ static void free_ir_loop(struct hlsl_ir_loop *loop)
>       vkd3d_free(loop);
>   }
>   
> +static void free_ir_resource_load(struct hlsl_ir_resource_load *load)
> +{
> +    hlsl_src_remove(&load->coords);
> +    hlsl_src_remove(&load->resource.offset);
> +    vkd3d_free(load);
> +}
> +
>   static void free_ir_store(struct hlsl_ir_store *store)
>   {
>       hlsl_src_remove(&store->rhs);
> @@ -1423,6 +1465,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
>               free_ir_loop(hlsl_ir_loop(node));
>               break;
>   
> +        case HLSL_IR_RESOURCE_LOAD:
> +            free_ir_resource_load(hlsl_ir_resource_load(node));
> +            break;
> +
>           case HLSL_IR_STORE:
>               free_ir_store(hlsl_ir_store(node));
>               break;
> diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
> index 64a90ffdc..e401971e1 100644
> --- a/libs/vkd3d-shader/hlsl.h
> +++ b/libs/vkd3d-shader/hlsl.h
> @@ -166,6 +166,7 @@ enum hlsl_ir_node_type
>       HLSL_IR_LOAD,
>       HLSL_IR_LOOP,
>       HLSL_IR_JUMP,
> +    HLSL_IR_RESOURCE_LOAD,
>       HLSL_IR_STORE,
>       HLSL_IR_SWIZZLE,
>   };
> @@ -239,6 +240,7 @@ struct hlsl_ir_var
>       uint32_t is_output_semantic : 1;
>       uint32_t is_uniform : 1;
>       uint32_t is_param : 1;
> +    uint32_t has_resource_access : 1;
>   };
>   
>   struct hlsl_ir_function
> @@ -366,6 +368,19 @@ struct hlsl_ir_load
>       struct hlsl_deref src;
>   };
>   
> +enum hlsl_resource_load_type
> +{
> +    HLSL_RESOURCE_LOAD,
> +};
> +
> +struct hlsl_ir_resource_load
> +{
> +    struct hlsl_ir_node node;
> +    enum hlsl_resource_load_type load_type;
> +    struct hlsl_deref resource;
> +    struct hlsl_src coords;
> +};
> +
>   struct hlsl_ir_store
>   {
>       struct hlsl_ir_node node;
> @@ -521,6 +536,12 @@ static inline struct hlsl_ir_loop *hlsl_ir_loop(const struct hlsl_ir_node *node)
>       return CONTAINING_RECORD(node, struct hlsl_ir_loop, node);
>   }
>   
> +static inline struct hlsl_ir_resource_load *hlsl_ir_resource_load(const struct hlsl_ir_node *node)
> +{
> +    assert(node->type == HLSL_IR_RESOURCE_LOAD);
> +    return CONTAINING_RECORD(node, struct hlsl_ir_resource_load, node);
> +}
> +
>   static inline struct hlsl_ir_store *hlsl_ir_store(const struct hlsl_ir_node *node)
>   {
>       assert(node->type == HLSL_IR_STORE);
> @@ -639,7 +660,7 @@ struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_exp
>   struct hlsl_buffer *hlsl_new_buffer(struct hlsl_ctx *ctx, enum hlsl_buffer_type type, const char *name,
>           const struct hlsl_reg_reservation *reservation, struct vkd3d_shader_location loc);
>   struct hlsl_ir_expr *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_type *type,
> -        struct vkd3d_shader_location *loc);
> +        const struct vkd3d_shader_location *loc);
>   struct hlsl_ir_expr *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *node);
>   struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type,
>           struct list *parameters, const struct hlsl_semantic *semantic, struct vkd3d_shader_location loc);
> @@ -648,6 +669,9 @@ struct hlsl_ir_jump *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type
>   struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
>           struct hlsl_type *type, struct vkd3d_shader_location loc);
>   struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc);
> +struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type,
> +        enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *offset,
> +        struct hlsl_ir_node *coords, const struct vkd3d_shader_location *loc);
>   struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs);
>   struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
>           struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc);
> diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
> index 32dd418d1..ae19cd1a7 100644
> --- a/libs/vkd3d-shader/hlsl.y
> +++ b/libs/vkd3d-shader/hlsl.y
> @@ -258,7 +258,7 @@ static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_typ
>   }
>   
>   static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs,
> -        struct hlsl_ir_node *node, struct hlsl_type *dst_type, struct vkd3d_shader_location *loc)
> +        struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc)
>   {
>       struct hlsl_type *src_type = node->data_type;
>       struct hlsl_ir_expr *cast;
> @@ -843,15 +843,21 @@ static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node)
>   
>           case HLSL_IR_EXPR:
>           case HLSL_IR_LOAD:
> +        case HLSL_IR_RESOURCE_LOAD:
>           case HLSL_IR_SWIZZLE:
>               FIXME("Unhandled type %s.\n", hlsl_node_type_to_string(node->type));
>               return 0;
>   
> +        case HLSL_IR_IF:
> +        case HLSL_IR_JUMP:
> +        case HLSL_IR_LOOP:
>           case HLSL_IR_STORE:
> -        default:
>               WARN("Invalid node type %s.\n", hlsl_node_type_to_string(node->type));
>               return 0;
>       }
> +
> +    assert(0);
> +    return 0;
>   }
>   
>   static bool expr_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2)
> @@ -1513,6 +1519,23 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
>       return statements_list;
>   }
>   
> +static unsigned int sampler_dim_count(enum hlsl_sampler_dim dim)
> +{
> +    switch (dim)
> +    {
> +        case HLSL_SAMPLER_DIM_1D:
> +            return 1;
> +        case HLSL_SAMPLER_DIM_2D:
> +            return 2;
> +        case HLSL_SAMPLER_DIM_3D:
> +        case HLSL_SAMPLER_DIM_CUBE:
> +            return 3;
> +        default:
> +            assert(0);
> +            return 0;
> +    }
> +}
> +
>   struct find_function_call_args
>   {
>       const struct parse_initializer *params;
> @@ -1757,6 +1780,65 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type
>       return params->instrs;
>   }
>   
> +static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object,
> +        const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
> +{
> +    const struct hlsl_type *object_type = object->data_type;
> +    struct hlsl_ir_load *object_load;
> +
> +    if (object_type->type != HLSL_CLASS_OBJECT || object_type->base_type != HLSL_TYPE_TEXTURE
> +            || object_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC)
> +    {
> +        struct vkd3d_string_buffer *string;
> +
> +        if ((string = hlsl_type_to_string(ctx, object_type)))
> +            hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
> +                    "Type '%s' does not have methods.", string->buffer);
> +        hlsl_release_string_buffer(ctx, string);
> +        return false;
> +    }
> +
> +    /* Only HLSL_IR_LOAD can return an object. */
> +    object_load = hlsl_ir_load(object);
> +
> +    if (!strcmp(name, "Load"))
> +    {
> +        const unsigned int sampler_dim = sampler_dim_count(object_type->sampler_dim);
> +        struct hlsl_ir_resource_load *load;
> +        struct hlsl_ir_node *coords;
> +
> +        if (params->args_count < 1 || params->args_count > 3)
> +        {
> +            hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
> +                    "Wrong number of arguments to method 'Load': expected 1, 2, or 3, but got %u.", params->args_count);
> +            return false;
> +        }
> +        if (params->args_count >= 2)
> +            FIXME("Ignoring index and/or offset parameter(s).\n");
> +
> +        /* -1 for zero-indexing; +1 for the mipmap level */
> +        if (!(coords = add_implicit_conversion(ctx, instrs, params->args[0],
> +                ctx->builtin_types.vector[HLSL_TYPE_INT][sampler_dim - 1 + 1], loc)))
> +            return false;
> +
> +        if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, HLSL_RESOURCE_LOAD,
> +                object_load->src.var, object_load->src.offset.node, coords, loc)))
> +            return false;
> +        list_add_tail(instrs, &load->node.entry);
> +        return true;
> +    }
> +    else
> +    {
> +        struct vkd3d_string_buffer *string;
> +
> +        if ((string = hlsl_type_to_string(ctx, object_type)))
> +            hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED,
> +                    "Method '%s' is not defined on type '%s'.", name, string->buffer);
> +        hlsl_release_string_buffer(ctx, string);
> +        return false;
> +    }
> +}
> +
>   }
>   
>   %locations
> @@ -3085,6 +3167,22 @@ postfix_expr:
>                   YYABORT;
>               }
>           }
> +    | postfix_expr '.' any_identifier '(' func_arguments ')'
> +        {
> +            struct hlsl_ir_node *object = node_from_list($1);
> +
> +            list_move_tail($1, $5.instrs);
> +            vkd3d_free($5.instrs);
> +
> +            if (!add_method_call(ctx, $1, object, $3, &$5, &@3))
> +            {
> +                hlsl_free_instr_list($1);
> +                vkd3d_free($5.args);
> +                YYABORT;
> +            }
> +            vkd3d_free($5.args);
> +            $$ = $1;
> +        }
>   
>   unary_expr:
>         postfix_expr
> diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
> index 9c9a38379..00fe76b2f 100644
> --- a/libs/vkd3d-shader/hlsl_codegen.c
> +++ b/libs/vkd3d-shader/hlsl_codegen.c
> @@ -503,6 +503,7 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
>           case HLSL_IR_CONSTANT:
>           case HLSL_IR_EXPR:
>           case HLSL_IR_LOAD:
> +        case HLSL_IR_RESOURCE_LOAD:
>           case HLSL_IR_SWIZZLE:
>               if (list_empty(&instr->uses))
>               {
> @@ -640,6 +641,16 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs
>                       loop_last ? loop_last : loop->next_index);
>               break;
>           }
> +        case HLSL_IR_RESOURCE_LOAD:
> +        {
> +            struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr);
> +
> +            load->resource.var->has_resource_access = 1;
> +            if (load->resource.offset.node)
> +                load->resource.offset.node->last_read = instr->index;
> +            load->coords.node->last_read = instr->index;
> +            break;
> +        }
>           case HLSL_IR_SWIZZLE:
>           {
>               struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(instr);
> @@ -665,7 +676,10 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
>       LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry)
>       {
>           LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
> +        {
>               var->first_write = var->last_read = 0;
> +            var->has_resource_access = 0;
> +        }
>       }
>   
>       LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
> diff --git a/libs/vkd3d-shader/hlsl_sm1.c b/libs/vkd3d-shader/hlsl_sm1.c
> index ee2870eca..9fc1b2210 100644
> --- a/libs/vkd3d-shader/hlsl_sm1.c
> +++ b/libs/vkd3d-shader/hlsl_sm1.c
> @@ -778,6 +778,11 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b
>                   hlsl_fixme(ctx, instr->loc, "SM1 matrix expression.");
>                   continue;
>               }
> +            else if (instr->data_type->type == HLSL_CLASS_OBJECT)
> +            {
> +                hlsl_fixme(ctx, instr->loc, "Object copy.\n");
> +                break;
> +            }
>   
>               assert(instr->data_type->type == HLSL_CLASS_SCALAR || instr->data_type->type == HLSL_CLASS_VECTOR);
>           }
> diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c
> index 328a8ba1b..b4fb8f2f7 100644
> --- a/libs/vkd3d-shader/hlsl_sm4.c
> +++ b/libs/vkd3d-shader/hlsl_sm4.c
> @@ -1286,6 +1286,11 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx,
>                   FIXME("Matrix operations need to be lowered.\n");
>                   break;
>               }
> +            else if (instr->data_type->type == HLSL_CLASS_OBJECT)
> +            {
> +                hlsl_fixme(ctx, instr->loc, "Object copy.\n");
> +                break;
> +            }
>   
>               assert(instr->data_type->type == HLSL_CLASS_SCALAR || instr->data_type->type == HLSL_CLASS_VECTOR);
>           }
> 



More information about the wine-devel mailing list