[gtk+/wip/otte/shader: 53/150] gskslexpression: Implement negation
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader: 53/150] gskslexpression: Implement negation
- Date: Sat, 21 Oct 2017 02:30:37 +0000 (UTC)
commit e6cb2345580ec83ad907648e2dfb509c3033174e
Author: Benjamin Otte <otte redhat com>
Date: Fri Sep 29 02:45:11 2017 +0200
gskslexpression: Implement negation
This includes adding gsk_sl_value_componentwise() which is not something
I particularly like, but it does its job - and will be useful for the
other operations.
gsk/gskslexpression.c | 181 ++++++++++++++++++++++++++++++++++++++++++++-
gsk/gskslvalue.c | 19 +++++
gsk/gskslvalueprivate.h | 3 +
gsk/gskspvwriterprivate.h | 27 +++++++
4 files changed, 228 insertions(+), 2 deletions(-)
---
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index ea99319..9c9de36 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -1055,6 +1055,142 @@ static const GskSlExpressionClass GSK_SL_EXPRESSION_SWIZZLE = {
gsk_sl_expression_swizzle_write_spv
};
+/* NEGATION */
+
+typedef struct _GskSlExpressionNegation GskSlExpressionNegation;
+
+struct _GskSlExpressionNegation {
+ GskSlExpression parent;
+
+ GskSlExpression *expr;
+};
+
+static void
+gsk_sl_expression_negation_free (GskSlExpression *expression)
+{
+ GskSlExpressionNegation *negation = (GskSlExpressionNegation *) expression;
+
+ gsk_sl_expression_unref (negation->expr);
+
+ g_slice_free (GskSlExpressionNegation, negation);
+}
+
+static void
+gsk_sl_expression_negation_print (const GskSlExpression *expression,
+ GString *string)
+{
+ const GskSlExpressionNegation *negation = (const GskSlExpressionNegation *) expression;
+
+ g_string_append (string, "-");
+ gsk_sl_expression_print (negation->expr, string);
+}
+
+static GskSlType *
+gsk_sl_expression_negation_get_return_type (const GskSlExpression *expression)
+{
+ const GskSlExpressionNegation *negation = (const GskSlExpressionNegation *) expression;
+
+ return gsk_sl_expression_get_return_type (negation->expr);
+}
+
+#define GSK_SL_OPERATION_FUNC(func,type,...) \
+static void \
+func (gpointer value, gpointer unused) \
+{ \
+ type x = *(type *) value; \
+ __VA_ARGS__ \
+ *(type *) value = x; \
+}
+GSK_SL_OPERATION_FUNC(gsk_sl_expression_negation_int, gint32, x = -x;)
+GSK_SL_OPERATION_FUNC(gsk_sl_expression_negation_uint, guint32, x = -x;)
+GSK_SL_OPERATION_FUNC(gsk_sl_expression_negation_float, float, x = -x;)
+GSK_SL_OPERATION_FUNC(gsk_sl_expression_negation_double, double, x = -x;)
+
+static GskSlValue *
+gsk_sl_expression_negation_get_constant (const GskSlExpression *expression)
+{
+ const GskSlExpressionNegation *negation = (const GskSlExpressionNegation *) expression;
+ GskSlValue *value;
+
+ value = gsk_sl_expression_get_constant (negation->expr);
+ if (value == NULL)
+ return NULL;
+
+ switch (gsk_sl_type_get_scalar_type (gsk_sl_value_get_type (value)))
+ {
+ case GSK_SL_INT:
+ gsk_sl_value_componentwise (value, gsk_sl_expression_negation_int, NULL);
+ break;
+ case GSK_SL_UINT:
+ gsk_sl_value_componentwise (value, gsk_sl_expression_negation_uint, NULL);
+ break;
+ case GSK_SL_FLOAT:
+ gsk_sl_value_componentwise (value, gsk_sl_expression_negation_float, NULL);
+ break;
+ case GSK_SL_DOUBLE:
+ gsk_sl_value_componentwise (value, gsk_sl_expression_negation_double, NULL);
+ break;
+ case GSK_SL_VOID:
+ case GSK_SL_BOOL:
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ return value;
+}
+
+static guint32
+gsk_sl_expression_negation_write_spv (const GskSlExpression *expression,
+ GskSpvWriter *writer)
+{
+ const GskSlExpressionNegation *negation = (const GskSlExpressionNegation *) expression;
+ guint type_id, expr_id, result_id;
+ GskSlType *type;
+
+ type = gsk_sl_expression_get_return_type (negation->expr);
+ type_id = gsk_spv_writer_get_id_for_type (writer, type);
+ expr_id = gsk_sl_expression_write_spv (negation->expr, writer);
+ result_id = gsk_spv_writer_next_id (writer);
+
+ switch (gsk_sl_type_get_scalar_type (type))
+ {
+ case GSK_SL_INT:
+ case GSK_SL_UINT:
+ gsk_spv_writer_add (writer,
+ GSK_SPV_WRITER_SECTION_CODE,
+ 4, GSK_SPV_OP_S_NEGATE,
+ (guint32[3]) { type_id,
+ result_id,
+ expr_id });
+ break;
+ case GSK_SL_FLOAT:
+ case GSK_SL_DOUBLE:
+ gsk_spv_writer_add (writer,
+ GSK_SPV_WRITER_SECTION_CODE,
+ 4, GSK_SPV_OP_F_NEGATE,
+ (guint32[3]) { type_id,
+ result_id,
+ expr_id });
+ break;
+ case GSK_SL_VOID:
+ case GSK_SL_BOOL:
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ return result_id;
+}
+
+static const GskSlExpressionClass GSK_SL_EXPRESSION_NEGATION = {
+ gsk_sl_expression_negation_free,
+ gsk_sl_expression_negation_print,
+ gsk_sl_expression_negation_get_return_type,
+ gsk_sl_expression_negation_get_constant,
+ gsk_sl_expression_negation_write_spv
+};
+
/* CONSTANT */
typedef struct _GskSlExpressionConstant GskSlExpressionConstant;
@@ -1071,6 +1207,8 @@ gsk_sl_expression_constant_free (GskSlExpression *expression)
GskSlExpressionConstant *constant = (GskSlExpressionConstant *) expression;
gsk_sl_value_free (constant->value);
+
+ g_slice_free (GskSlExpressionConstant, constant);
}
static void
@@ -1496,9 +1634,48 @@ gsk_sl_expression_parse_postfix (GskSlScope *scope,
static GskSlExpression *
gsk_sl_expression_parse_unary (GskSlScope *scope,
- GskSlPreprocessor *stream)
+ GskSlPreprocessor *preproc)
{
- return gsk_sl_expression_parse_postfix (scope, stream);
+ const GskSlToken *token;
+ GskSlType *type;
+
+ token = gsk_sl_preprocessor_get (preproc);
+
+ if (gsk_sl_token_is (token, GSK_SL_TOKEN_DASH))
+ {
+ GskSlExpressionNegation *negation = gsk_sl_expression_new (GskSlExpressionNegation,
&GSK_SL_EXPRESSION_NEGATION);
+ GskSlExpression *expr;
+
+ gsk_sl_preprocessor_consume (preproc, negation);
+ negation->expr = gsk_sl_expression_parse_unary (scope, preproc);
+ type = gsk_sl_expression_get_return_type (negation->expr);
+ if (!gsk_sl_type_is_scalar (type) && !gsk_sl_type_is_vector (type) && !gsk_sl_type_is_matrix (type))
+ {
+ gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH,
+ "Negation only works on scalars, vectors and matrices, not on %s.",
+ gsk_sl_type_get_name (type));
+ expr = gsk_sl_expression_ref (negation->expr);
+ gsk_sl_expression_unref ((GskSlExpression *) negation);
+ return expr;
+ }
+ else if (gsk_sl_type_get_scalar_type (type) == GSK_SL_BOOL)
+ {
+ gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH,
+ "Negation does not work on boolean types like %s.",
+ gsk_sl_type_get_name (type));
+ expr = gsk_sl_expression_ref (negation->expr);
+ gsk_sl_expression_unref ((GskSlExpression *) negation);
+ return expr;
+ }
+ else
+ {
+ return (GskSlExpression *) negation;
+ }
+ }
+ else
+ {
+ return gsk_sl_expression_parse_postfix (scope, preproc);
+ }
}
static GskSlExpression *
diff --git a/gsk/gskslvalue.c b/gsk/gskslvalue.c
index 6972ff7..304fafe 100644
--- a/gsk/gskslvalue.c
+++ b/gsk/gskslvalue.c
@@ -195,6 +195,25 @@ gsk_sl_value_free (GskSlValue *value)
}
void
+gsk_sl_value_componentwise (GskSlValue *value,
+ void (* func) (gpointer, gpointer),
+ gpointer user_data)
+{
+ gsize stride;
+ gsize i, n;
+
+ g_return_if_fail (gsk_sl_type_is_scalar (value->type) || gsk_sl_type_is_vector (value->type) ||
gsk_sl_type_is_matrix (value->type));
+
+ stride = gsk_sl_type_get_size (gsk_sl_type_get_scalar (gsk_sl_type_get_scalar_type (value->type)));
+ n = gsk_sl_type_get_size (value->type) / stride;
+
+ for (i = 0; i < n; i++)
+ {
+ func ((guchar *) value->data + stride * i, user_data);
+ }
+}
+
+void
gsk_sl_value_print (const GskSlValue *value,
GString *string)
{
diff --git a/gsk/gskslvalueprivate.h b/gsk/gskslvalueprivate.h
index c4e7c59..3a314a6 100644
--- a/gsk/gskslvalueprivate.h
+++ b/gsk/gskslvalueprivate.h
@@ -35,6 +35,9 @@ GskSlValue * gsk_sl_value_new_member (GskSlValue
GskSlValue * gsk_sl_value_copy (const GskSlValue *source);
void gsk_sl_value_free (GskSlValue *value);
+void gsk_sl_value_componentwise (GskSlValue *value,
+ void (* func) (gpointer, gpointer),
+ gpointer user_data);
void gsk_sl_value_print (const GskSlValue *value,
GString *string);
diff --git a/gsk/gskspvwriterprivate.h b/gsk/gskspvwriterprivate.h
index c0f3d5c..81b2af1 100644
--- a/gsk/gskspvwriterprivate.h
+++ b/gsk/gskspvwriterprivate.h
@@ -119,6 +119,33 @@ typedef enum {
GSK_SPV_OP_GENERIC_CAST_TO_PTR = 122,
GSK_SPV_OP_GENERIC_CAST_TO_PTR_EXPLICIT = 123,
GSK_SPV_OP_BITCAST = 124,
+ GSK_SPV_OP_S_NEGATE = 126,
+ GSK_SPV_OP_F_NEGATE = 127,
+ GSK_SPV_OP_I_ADD = 128,
+ GSK_SPV_OP_F_ADD = 129,
+ GSK_SPV_OP_I_SUB = 130,
+ GSK_SPV_OP_F_SUB = 131,
+ GSK_SPV_OP_I_MUL = 132,
+ GSK_SPV_OP_F_MUL = 133,
+ GSK_SPV_OP_U_DIV = 134,
+ GSK_SPV_OP_S_DIV = 135,
+ GSK_SPV_OP_F_DIV = 136,
+ GSK_SPV_OP_U_MOD = 137,
+ GSK_SPV_OP_S_REM = 138,
+ GSK_SPV_OP_S_MOD = 139,
+ GSK_SPV_OP_F_REM = 140,
+ GSK_SPV_OP_F_MOD = 141,
+ GSK_SPV_OP_VECTOR_TIMES_SCALAR = 142,
+ GSK_SPV_OP_MATRIX_TIMES_SCALAR = 143,
+ GSK_SPV_OP_VECTOR_TIMES_MATRIX = 144,
+ GSK_SPV_OP_MATRIX_TIMES_VECTOR = 145,
+ GSK_SPV_OP_MATRIX_TIMES_MATRIX = 146,
+ GSK_SPV_OP_OUTER_PRODUCT = 147,
+ GSK_SPV_OP_DOT = 148,
+ GSK_SPV_OP_I_ADD_CARRY = 149,
+ GSK_SPV_OP_I_SUB_BORROW = 150,
+ GSK_SPV_OP_U_MUL_EXTENDED = 151,
+ GSK_SPV_OP_S_MUL_EXTENDED = 152,
GSK_SPV_OP_PHI = 245,
GSK_SPV_OP_LOOP_MERGE = 246,
GSK_SPV_OP_SELECTION_MERGE = 247,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]