gsksl: Add support for parsing members of struct variables
This includes adding the concept of members to GskSlType.
This commit is contained in:
@@ -794,6 +794,95 @@ static const GskSlExpressionClass GSK_SL_EXPRESSION_FUNCTION_CALL = {
|
||||
gsk_sl_expression_function_call_write_spv
|
||||
};
|
||||
|
||||
/* MEMBER */
|
||||
|
||||
typedef struct _GskSlExpressionMember GskSlExpressionMember;
|
||||
|
||||
struct _GskSlExpressionMember {
|
||||
GskSlExpression parent;
|
||||
|
||||
GskSlExpression *expr;
|
||||
guint id;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_expression_member_free (GskSlExpression *expression)
|
||||
{
|
||||
GskSlExpressionMember *member = (GskSlExpressionMember *) expression;
|
||||
|
||||
gsk_sl_expression_unref (member->expr);
|
||||
|
||||
g_slice_free (GskSlExpressionMember, member);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_expression_member_print (const GskSlExpression *expression,
|
||||
GString *string)
|
||||
{
|
||||
const GskSlExpressionMember *member = (const GskSlExpressionMember *) expression;
|
||||
|
||||
gsk_sl_expression_print (member->expr, string);
|
||||
g_string_append (string, ".");
|
||||
g_string_append (string, gsk_sl_type_get_member_name (gsk_sl_expression_get_return_type (member->expr), member->id));
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_expression_member_get_return_type (const GskSlExpression *expression)
|
||||
{
|
||||
const GskSlExpressionMember *member = (const GskSlExpressionMember *) expression;
|
||||
|
||||
return gsk_sl_type_get_member_type (gsk_sl_expression_get_return_type (member->expr), member->id);
|
||||
}
|
||||
|
||||
static GskSlValue *
|
||||
gsk_sl_expression_member_get_constant (const GskSlExpression *expression)
|
||||
{
|
||||
const GskSlExpressionMember *member = (const GskSlExpressionMember *) expression;
|
||||
GskSlValue *result, *value;
|
||||
|
||||
value = gsk_sl_expression_get_constant (member->expr);
|
||||
if (value == NULL)
|
||||
return NULL;
|
||||
|
||||
result = gsk_sl_value_new_member (value, member->id);
|
||||
|
||||
gsk_sl_value_free (value);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_expression_member_write_spv (const GskSlExpression *expression,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
const GskSlExpressionMember *member = (const GskSlExpressionMember *) expression;
|
||||
GskSlType *type;
|
||||
guint32 expr_id, type_id, result_id;
|
||||
|
||||
type = gsk_sl_expression_get_return_type (member->expr);
|
||||
type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_member_type (type, member->id));
|
||||
expr_id = gsk_sl_expression_write_spv (member->expr, writer);
|
||||
result_id = gsk_spv_writer_next_id (writer);
|
||||
|
||||
gsk_spv_writer_add (writer,
|
||||
GSK_SPV_WRITER_SECTION_CODE,
|
||||
5, GSK_SPV_OP_ACCESS_CHAIN,
|
||||
(guint32[4]) { type_id,
|
||||
result_id,
|
||||
expr_id,
|
||||
member->id });
|
||||
|
||||
return result_id;
|
||||
}
|
||||
|
||||
static const GskSlExpressionClass GSK_SL_EXPRESSION_MEMBER = {
|
||||
gsk_sl_expression_member_free,
|
||||
gsk_sl_expression_member_print,
|
||||
gsk_sl_expression_member_get_return_type,
|
||||
gsk_sl_expression_member_get_constant,
|
||||
gsk_sl_expression_member_write_spv
|
||||
};
|
||||
|
||||
/* SWIZZLE */
|
||||
|
||||
typedef enum {
|
||||
@@ -1268,6 +1357,7 @@ gsk_sl_expression_parse_field_selection (GskSlScope *scope,
|
||||
const char *name)
|
||||
{
|
||||
GskSlType *type;
|
||||
guint n;
|
||||
|
||||
if (g_str_equal (name, "length"))
|
||||
{
|
||||
@@ -1327,6 +1417,16 @@ gsk_sl_expression_parse_field_selection (GskSlScope *scope,
|
||||
|
||||
return (GskSlExpression *) swizzle;
|
||||
}
|
||||
else if (gsk_sl_type_find_member (type, name, &n, NULL, NULL))
|
||||
{
|
||||
GskSlExpressionMember *member;
|
||||
|
||||
member = gsk_sl_expression_new (GskSlExpressionMember, &GSK_SL_EXPRESSION_MEMBER);
|
||||
member->expr = expr;
|
||||
member->id = n;
|
||||
|
||||
return (GskSlExpression *) member;
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Type %s has no fields to select.", gsk_sl_type_get_name (type));
|
||||
|
||||
198
gsk/gsksltype.c
198
gsk/gsksltype.c
@@ -31,8 +31,16 @@
|
||||
|
||||
#define N_SCALAR_TYPES 6
|
||||
|
||||
typedef struct _GskSlTypeMember GskSlTypeMember;
|
||||
typedef struct _GskSlTypeClass GskSlTypeClass;
|
||||
|
||||
struct _GskSlTypeMember {
|
||||
GskSlType *type;
|
||||
char *name;
|
||||
gsize offset;
|
||||
};
|
||||
|
||||
|
||||
struct _GskSlType
|
||||
{
|
||||
const GskSlTypeClass *class;
|
||||
@@ -42,13 +50,15 @@ struct _GskSlType
|
||||
|
||||
struct _GskSlTypeClass {
|
||||
void (* free) (GskSlType *type);
|
||||
|
||||
const char * (* get_name) (const GskSlType *type);
|
||||
GskSlScalarType (* get_scalar_type) (const GskSlType *type);
|
||||
GskSlType * (* get_index_type) (const GskSlType *type);
|
||||
gsize (* get_index_stride) (const GskSlType *type);
|
||||
guint (* get_length) (const GskSlType *type);
|
||||
gsize (* get_size) (const GskSlType *type);
|
||||
guint (* get_n_members) (const GskSlType *type);
|
||||
const GskSlTypeMember * (* get_member) (const GskSlType *type,
|
||||
guint i);
|
||||
gboolean (* can_convert) (const GskSlType *target,
|
||||
const GskSlType *source);
|
||||
guint32 (* write_spv) (GskSlType *type,
|
||||
@@ -387,6 +397,19 @@ gsk_sl_type_scalar_get_size (const GskSlType *type)
|
||||
return scalar_infos[scalar->scalar].size;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_sl_type_scalar_get_n_members (const GskSlType *type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const GskSlTypeMember *
|
||||
gsk_sl_type_scalar_get_member (const GskSlType *type,
|
||||
guint n)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_type_scalar_can_convert (const GskSlType *target,
|
||||
const GskSlType *source)
|
||||
@@ -499,6 +522,8 @@ static const GskSlTypeClass GSK_SL_TYPE_SCALAR = {
|
||||
gsk_sl_type_scalar_get_index_stride,
|
||||
gsk_sl_type_scalar_get_length,
|
||||
gsk_sl_type_scalar_get_size,
|
||||
gsk_sl_type_scalar_get_n_members,
|
||||
gsk_sl_type_scalar_get_member,
|
||||
gsk_sl_type_scalar_can_convert,
|
||||
gsk_sl_type_scalar_write_spv,
|
||||
gsk_sl_type_scalar_print_value,
|
||||
@@ -571,6 +596,19 @@ gsk_sl_type_vector_get_size (const GskSlType *type)
|
||||
return vector->length * scalar_infos[vector->scalar].size;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_sl_type_vector_get_n_members (const GskSlType *type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const GskSlTypeMember *
|
||||
gsk_sl_type_vector_get_member (const GskSlType *type,
|
||||
guint n)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_type_vector_can_convert (const GskSlType *target,
|
||||
const GskSlType *source)
|
||||
@@ -672,6 +710,8 @@ static const GskSlTypeClass GSK_SL_TYPE_VECTOR = {
|
||||
gsk_sl_type_vector_get_index_stride,
|
||||
gsk_sl_type_vector_get_length,
|
||||
gsk_sl_type_vector_get_size,
|
||||
gsk_sl_type_vector_get_n_members,
|
||||
gsk_sl_type_vector_get_member,
|
||||
gsk_sl_type_vector_can_convert,
|
||||
gsk_sl_type_vector_write_spv,
|
||||
gsk_sl_type_vector_print_value,
|
||||
@@ -745,6 +785,19 @@ gsk_sl_type_matrix_get_size (const GskSlType *type)
|
||||
return matrix->columns * matrix->rows * scalar_infos[matrix->scalar].size;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_sl_type_matrix_get_n_members (const GskSlType *type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const GskSlTypeMember *
|
||||
gsk_sl_type_matrix_get_member (const GskSlType *type,
|
||||
guint n)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_type_matrix_can_convert (const GskSlType *target,
|
||||
const GskSlType *source)
|
||||
@@ -847,6 +900,8 @@ static const GskSlTypeClass GSK_SL_TYPE_MATRIX = {
|
||||
gsk_sl_type_matrix_get_index_stride,
|
||||
gsk_sl_type_matrix_get_length,
|
||||
gsk_sl_type_matrix_get_size,
|
||||
gsk_sl_type_matrix_get_n_members,
|
||||
gsk_sl_type_matrix_get_member,
|
||||
gsk_sl_type_matrix_can_convert,
|
||||
gsk_sl_type_matrix_write_spv,
|
||||
gsk_sl_type_matrix_print_value,
|
||||
@@ -855,15 +910,8 @@ static const GskSlTypeClass GSK_SL_TYPE_MATRIX = {
|
||||
|
||||
/* STRUCT */
|
||||
|
||||
typedef struct _GskSlTypeMember GskSlTypeMember;
|
||||
typedef struct _GskSlTypeStruct GskSlTypeStruct;
|
||||
|
||||
struct _GskSlTypeMember {
|
||||
GskSlType *type;
|
||||
char *name;
|
||||
gsize offset;
|
||||
};
|
||||
|
||||
struct _GskSlTypeStruct {
|
||||
GskSlType parent;
|
||||
|
||||
@@ -893,55 +941,72 @@ gsk_sl_type_struct_free (GskSlType *type)
|
||||
}
|
||||
|
||||
static const char *
|
||||
gsk_sl_type_struct_get_name (GskSlType *type)
|
||||
gsk_sl_type_struct_get_name (const GskSlType *type)
|
||||
{
|
||||
GskSlTypeStruct *struc = (GskSlTypeStruct *) type;
|
||||
const GskSlTypeStruct *struc = (const GskSlTypeStruct *) type;
|
||||
|
||||
return struc->name;
|
||||
}
|
||||
|
||||
static GskSlScalarType
|
||||
gsk_sl_type_struct_get_scalar_type (GskSlType *type)
|
||||
gsk_sl_type_struct_get_scalar_type (const GskSlType *type)
|
||||
{
|
||||
return GSK_SL_VOID;
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_type_struct_get_index_type (GskSlType *type)
|
||||
gsk_sl_type_struct_get_index_type (const GskSlType *type)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gsize
|
||||
gsk_sl_type_struct_get_index_stride (GskSlType *type)
|
||||
gsk_sl_type_struct_get_index_stride (const GskSlType *type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_sl_type_struct_get_length (GskSlType *type)
|
||||
gsk_sl_type_struct_get_length (const GskSlType *type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gsize
|
||||
gsk_sl_type_struct_get_size (GskSlType *type)
|
||||
gsk_sl_type_struct_get_size (const GskSlType *type)
|
||||
{
|
||||
GskSlTypeStruct *struc = (GskSlTypeStruct *) type;
|
||||
const GskSlTypeStruct *struc = (const GskSlTypeStruct *) type;
|
||||
|
||||
return struc->size;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_sl_type_struct_get_n_members (const GskSlType *type)
|
||||
{
|
||||
const GskSlTypeStruct *struc = (const GskSlTypeStruct *) type;
|
||||
|
||||
return struc->n_members;
|
||||
}
|
||||
|
||||
static const GskSlTypeMember *
|
||||
gsk_sl_type_struct_get_member (const GskSlType *type,
|
||||
guint n)
|
||||
{
|
||||
const GskSlTypeStruct *struc = (const GskSlTypeStruct *) type;
|
||||
|
||||
return &struc->members[n];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_type_struct_can_convert (GskSlType *target,
|
||||
GskSlType *source)
|
||||
gsk_sl_type_struct_can_convert (const GskSlType *target,
|
||||
const GskSlType *source)
|
||||
{
|
||||
return gsk_sl_type_equal (target, source);
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_type_struct_write_spv (const GskSlType *type,
|
||||
GskSpvWriter *writer)
|
||||
gsk_sl_type_struct_write_spv (GskSlType *type,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
GskSlTypeStruct *struc = (GskSlTypeStruct *) type;
|
||||
guint32 ids[struc->n_members + 1];
|
||||
@@ -965,9 +1030,9 @@ gsk_sl_type_struct_write_spv (const GskSlType *type,
|
||||
static void
|
||||
gsk_sl_type_struct_print_value (const GskSlType *type,
|
||||
GString *string,
|
||||
gpointer value)
|
||||
gconstpointer value)
|
||||
{
|
||||
GskSlTypeStruct *struc = (GskSlTypeStruct *) type;
|
||||
const GskSlTypeStruct *struc = (const GskSlTypeStruct *) type;
|
||||
guint i;
|
||||
|
||||
g_string_append (string, struc->name);
|
||||
@@ -986,20 +1051,15 @@ gsk_sl_type_struct_print_value (const GskSlType *type,
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_type_struct_write_value_spv (GskSlType *type,
|
||||
GskSpvWriter *writer,
|
||||
gpointer value)
|
||||
gsk_sl_type_struct_write_value_spv (GskSlType *type,
|
||||
GskSpvWriter *writer,
|
||||
gconstpointer value)
|
||||
{
|
||||
GskSlTypeStruct *struc = (GskSlTypeStruct *) type;
|
||||
guint32 ids[struc->n_members + 2];
|
||||
GskSlType *vector_type;
|
||||
GskSlValue *v;
|
||||
guchar *data;
|
||||
guint i;
|
||||
|
||||
data = value;
|
||||
vector_type = gsk_sl_type_get_index_type (type);
|
||||
|
||||
ids[0] = gsk_spv_writer_get_id_for_type (writer, type);
|
||||
for (i = 0; i < struc->n_members; i++)
|
||||
{
|
||||
@@ -1008,7 +1068,6 @@ gsk_sl_type_struct_write_value_spv (GskSlType *type,
|
||||
NULL, NULL);
|
||||
ids[2 + i] = gsk_spv_writer_get_id_for_value (writer, v);
|
||||
gsk_sl_value_free (v);
|
||||
data += gsk_sl_type_get_size (vector_type);
|
||||
}
|
||||
|
||||
ids[1] = gsk_spv_writer_next_id (writer);
|
||||
@@ -1030,6 +1089,8 @@ static const GskSlTypeClass GSK_SL_TYPE_STRUCT = {
|
||||
gsk_sl_type_struct_get_index_stride,
|
||||
gsk_sl_type_struct_get_length,
|
||||
gsk_sl_type_struct_get_size,
|
||||
gsk_sl_type_struct_get_n_members,
|
||||
gsk_sl_type_struct_get_member,
|
||||
gsk_sl_type_struct_can_convert,
|
||||
gsk_sl_type_struct_write_spv,
|
||||
gsk_sl_type_struct_print_value,
|
||||
@@ -1482,6 +1543,81 @@ gsk_sl_type_get_size (const GskSlType *type)
|
||||
return type->class->get_size (type);
|
||||
}
|
||||
|
||||
guint
|
||||
gsk_sl_type_get_n_members (const GskSlType *type)
|
||||
{
|
||||
return type->class->get_n_members (type);
|
||||
}
|
||||
|
||||
static const GskSlTypeMember *
|
||||
gsk_sl_type_get_member (const GskSlType *type,
|
||||
guint n)
|
||||
{
|
||||
return type->class->get_member (type, n);
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_type_get_member_type (const GskSlType *type,
|
||||
guint n)
|
||||
{
|
||||
const GskSlTypeMember *member;
|
||||
|
||||
member = gsk_sl_type_get_member (type, n);
|
||||
|
||||
return member->type;
|
||||
}
|
||||
|
||||
const char *
|
||||
gsk_sl_type_get_member_name (const GskSlType *type,
|
||||
guint n)
|
||||
{
|
||||
const GskSlTypeMember *member;
|
||||
|
||||
member = gsk_sl_type_get_member (type, n);
|
||||
|
||||
return member->name;
|
||||
}
|
||||
|
||||
gsize
|
||||
gsk_sl_type_get_member_offset (const GskSlType *type,
|
||||
guint n)
|
||||
{
|
||||
const GskSlTypeMember *member;
|
||||
|
||||
member = gsk_sl_type_get_member (type, n);
|
||||
|
||||
return member->offset;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_type_find_member (const GskSlType *type,
|
||||
const char *name,
|
||||
guint *out_index,
|
||||
GskSlType **out_type,
|
||||
gsize *out_offset)
|
||||
{
|
||||
const GskSlTypeMember *member;
|
||||
guint i, n;
|
||||
|
||||
n = gsk_sl_type_get_n_members (type);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
member = gsk_sl_type_get_member (type, i);
|
||||
if (g_str_equal (member->name, name))
|
||||
{
|
||||
if (out_index)
|
||||
*out_index = i;
|
||||
if (out_type)
|
||||
*out_type = member->type;
|
||||
if (out_offset)
|
||||
*out_offset = member->offset;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_scalar_type_can_convert (GskSlScalarType target,
|
||||
GskSlScalarType source)
|
||||
|
||||
@@ -59,6 +59,18 @@ GskSlType * gsk_sl_type_get_index_type (const GskSlType
|
||||
gsize gsk_sl_type_get_index_stride (const GskSlType *type);
|
||||
guint gsk_sl_type_get_length (const GskSlType *type);
|
||||
gsize gsk_sl_type_get_size (const GskSlType *type);
|
||||
guint gsk_sl_type_get_n_members (const GskSlType *type);
|
||||
GskSlType * gsk_sl_type_get_member_type (const GskSlType *type,
|
||||
guint n);
|
||||
const char * gsk_sl_type_get_member_name (const GskSlType *type,
|
||||
guint n);
|
||||
gsize gsk_sl_type_get_member_offset (const GskSlType *type,
|
||||
guint n);
|
||||
gboolean gsk_sl_type_find_member (const GskSlType *type,
|
||||
const char *name,
|
||||
guint *out_index,
|
||||
GskSlType **out_type,
|
||||
gsize *out_offset);
|
||||
gboolean gsk_sl_scalar_type_can_convert (GskSlScalarType target,
|
||||
GskSlScalarType source);
|
||||
gboolean gsk_sl_type_can_convert (const GskSlType *target,
|
||||
|
||||
@@ -158,6 +158,18 @@ gsk_sl_value_new_convert (GskSlValue *source,
|
||||
}
|
||||
}
|
||||
|
||||
GskSlValue *
|
||||
gsk_sl_value_new_member (GskSlValue *value,
|
||||
guint n)
|
||||
{
|
||||
gpointer data;
|
||||
|
||||
data = g_memdup ((guchar *) value->data + gsk_sl_type_get_member_offset (value->type, n),
|
||||
gsk_sl_type_get_size (gsk_sl_type_get_member_type (value->type, n)));
|
||||
|
||||
return gsk_sl_value_new_for_data (value->type, data, g_free, data);
|
||||
}
|
||||
|
||||
GskSlValue *
|
||||
gsk_sl_value_copy (const GskSlValue *source)
|
||||
{
|
||||
|
||||
@@ -30,6 +30,8 @@ GskSlValue * gsk_sl_value_new_for_data (GskSlType
|
||||
gpointer user_data);
|
||||
GskSlValue * gsk_sl_value_new_convert (GskSlValue *source,
|
||||
GskSlType *new_type);
|
||||
GskSlValue * gsk_sl_value_new_member (GskSlValue *value,
|
||||
guint n);
|
||||
GskSlValue * gsk_sl_value_copy (const GskSlValue *source);
|
||||
void gsk_sl_value_free (GskSlValue *value);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user