summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2017-10-26 17:29:31 +0200
committerBenjamin Otte <otte@redhat.com>2017-10-30 02:58:03 +0100
commit92fd8ccdee11cbb9f7a88720c5dd7bebdbefb03c (patch)
treed3dc1214b4ede19ce24197ab22ae92ec4ec3f5e8
parent73ec3734bd8facdfbfff7224e01af6f9c30ae0c9 (diff)
downloadgtk+-92fd8ccdee11cbb9f7a88720c5dd7bebdbefb03c.tar.gz
gskslbinary: Implement modulo
-rw-r--r--gsk/gskslbinary.c224
1 files changed, 172 insertions, 52 deletions
diff --git a/gsk/gskslbinary.c b/gsk/gskslbinary.c
index 40ca4040f8..9ab1c23333 100644
--- a/gsk/gskslbinary.c
+++ b/gsk/gskslbinary.c
@@ -1205,6 +1205,178 @@ static const GskSlBinary GSK_SL_BINARY_SUBTRACTION = {
gsk_sl_subtraction_write_spv
};
+/* MODULO */
+
+static GskSlType *
+gsk_sl_bitwise_check_type (GskSlPreprocessor *preproc,
+ GskSlType *ltype,
+ GskSlType *rtype)
+{
+ GskSlScalarType lscalar, rscalar;
+
+ lscalar = gsk_sl_type_get_scalar_type (ltype);
+ if (lscalar != GSK_SL_INT && lscalar != GSK_SL_UINT)
+ {
+ gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Left operand %s is not an integer type.", gsk_sl_type_get_name (ltype));
+ return NULL;
+ }
+ rscalar = gsk_sl_type_get_scalar_type (ltype);
+ if (rscalar != GSK_SL_INT && rscalar != GSK_SL_UINT)
+ {
+ gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Right operand %s is not an integer type.", gsk_sl_type_get_name (rtype));
+ return NULL;
+ }
+ if (!gsk_sl_type_is_scalar (ltype) && !gsk_sl_type_is_vector (ltype))
+ {
+ gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Left operand %s is neither a scalar nor a vector.", gsk_sl_type_get_name (ltype));
+ return NULL;
+ }
+ if (!gsk_sl_type_is_scalar (rtype) && !gsk_sl_type_is_vector (rtype))
+ {
+ gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Right operand %s is neither a scalar nor a vector.", gsk_sl_type_get_name (rtype));
+ return NULL;
+ }
+ if (gsk_sl_type_is_vector (ltype) && gsk_sl_type_is_vector (rtype) &&
+ gsk_sl_type_get_length (ltype) != gsk_sl_type_get_length (rtype))
+ {
+ gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH,
+ "Vector operands %s and %s do not have the same length.",
+ gsk_sl_type_get_name (ltype), gsk_sl_type_get_name (rtype));
+ return NULL;
+ }
+
+ rscalar = lscalar == GSK_SL_UINT ? GSK_SL_UINT : rscalar;
+ if (gsk_sl_type_is_scalar (ltype) && gsk_sl_type_is_scalar (rtype))
+ return gsk_sl_type_get_scalar (rscalar);
+ else
+ return gsk_sl_type_get_vector (rscalar, gsk_sl_type_get_length (ltype));
+}
+
+GSK_SL_BINARY_FUNC_SCALAR(gsk_sl_expression_modulo_int, gint32, x = y ? x % y : x;)
+GSK_SL_BINARY_FUNC_SCALAR(gsk_sl_expression_modulo_uint, guint32, x = y ? x % y : x;)
+GSK_SL_BINARY_FUNC_SCALAR(gsk_sl_expression_modulo_int_inv, gint32, x = x ? y % x : y;)
+GSK_SL_BINARY_FUNC_SCALAR(gsk_sl_expression_modulo_uint_inv, guint32, x = x ? y % x : y;)
+static void (* modulo_funcs[]) (gpointer, gpointer) = {
+ [GSK_SL_INT] = gsk_sl_expression_modulo_int,
+ [GSK_SL_UINT] = gsk_sl_expression_modulo_uint,
+};
+static void (* modulo_inv_funcs[]) (gpointer, gpointer) = {
+ [GSK_SL_INT] = gsk_sl_expression_modulo_int_inv,
+ [GSK_SL_UINT] = gsk_sl_expression_modulo_uint_inv,
+};
+
+static GskSlValue *
+gsk_sl_modulo_get_constant (GskSlType *type,
+ GskSlValue *lvalue,
+ GskSlValue *rvalue)
+{
+ GskSlValue *result;
+ GskSlType *ltype, *rtype;
+ GskSlScalarType scalar;
+ gsize ln, rn;
+
+ scalar = gsk_sl_type_get_scalar_type (type);
+ lvalue = gsk_sl_value_convert_components (lvalue, scalar);
+ rvalue = gsk_sl_value_convert_components (rvalue, scalar);
+ ltype = gsk_sl_value_get_type (lvalue);
+ rtype = gsk_sl_value_get_type (rvalue);
+
+ ln = gsk_sl_type_get_n_components (ltype);
+ rn = gsk_sl_type_get_n_components (rtype);
+ if (ln == 1)
+ {
+ gsk_sl_value_componentwise (rvalue, modulo_inv_funcs[scalar], gsk_sl_value_get_data (lvalue));
+ gsk_sl_value_free (lvalue);
+ result = rvalue;
+ }
+ else if (rn == 1)
+ {
+ gsk_sl_value_componentwise (lvalue, modulo_funcs[scalar], gsk_sl_value_get_data (rvalue));
+ gsk_sl_value_free (rvalue);
+ result = lvalue;
+ }
+ else
+ {
+ guchar *ldata, *rdata;
+ gsize i, stride;
+
+ stride = gsk_sl_scalar_type_get_size (scalar);
+ ldata = gsk_sl_value_get_data (lvalue);
+ rdata = gsk_sl_value_get_data (rvalue);
+ for (i = 0; i < ln; i++)
+ {
+ modulo_funcs[scalar] (ldata + i * stride, rdata + i * stride);
+ }
+ gsk_sl_value_free (rvalue);
+ result = lvalue;
+ }
+
+ return result;
+}
+
+static guint32
+gsk_sl_modulo_write_spv (GskSpvWriter *writer,
+ GskSlType *type,
+ GskSlType *ltype,
+ guint32 left_id,
+ GskSlType *rtype,
+ guint32 right_id)
+{
+ if (gsk_sl_type_get_scalar_type (ltype) != gsk_sl_type_get_scalar_type (type))
+ {
+ GskSlType *new_type = gsk_sl_type_get_matching (ltype, gsk_sl_type_get_scalar_type (type));
+ left_id = gsk_spv_writer_convert (writer, left_id, ltype, new_type);
+ ltype = new_type;
+ }
+ if (gsk_sl_type_get_scalar_type (rtype) != gsk_sl_type_get_scalar_type (type))
+ {
+ GskSlType *new_type = gsk_sl_type_get_matching (rtype, gsk_sl_type_get_scalar_type (type));
+ right_id = gsk_spv_writer_convert (writer, right_id, rtype, new_type);
+ rtype = new_type;
+ }
+
+ if (gsk_sl_type_is_scalar (ltype) && gsk_sl_type_is_vector (rtype))
+ {
+ guint32 tmp_id = gsk_spv_writer_composite_construct (writer,
+ type,
+ (guint32[4]) { left_id, left_id, left_id, left_id },
+ gsk_sl_type_get_length (rtype));
+ left_id = tmp_id;
+ }
+ else if (gsk_sl_type_is_scalar (rtype) && gsk_sl_type_is_vector (ltype))
+ {
+ guint32 tmp_id = gsk_spv_writer_composite_construct (writer,
+ type,
+ (guint32[4]) { right_id, right_id, right_id, right_id },
+ gsk_sl_type_get_length (ltype));
+ right_id = tmp_id;
+ }
+
+ switch (gsk_sl_type_get_scalar_type (type))
+ {
+ case GSK_SL_INT:
+ return gsk_spv_writer_s_mod (writer, type, left_id, right_id);
+
+ case GSK_SL_UINT:
+ return gsk_spv_writer_u_mod (writer, type, left_id, right_id);
+
+ case GSK_SL_FLOAT:
+ case GSK_SL_DOUBLE:
+ case GSK_SL_VOID:
+ case GSK_SL_BOOL:
+ default:
+ g_assert_not_reached ();
+ return 0;
+ }
+}
+
+static const GskSlBinary GSK_SL_BINARY_MODULO = {
+ "%",
+ gsk_sl_bitwise_check_type,
+ gsk_sl_modulo_get_constant,
+ gsk_sl_modulo_write_spv
+};
+
/* LESS */
static GskSlType *
@@ -1790,51 +1962,6 @@ static const GskSlBinary GSK_SL_BINARY_NOT_EQUAL = {
/* UNIMPLEMENTED */
static GskSlType *
-gsk_sl_bitwise_check_type (GskSlPreprocessor *preproc,
- GskSlType *ltype,
- GskSlType *rtype)
-{
- GskSlScalarType lscalar, rscalar;
-
- lscalar = gsk_sl_type_get_scalar_type (ltype);
- if (lscalar != GSK_SL_INT && lscalar != GSK_SL_UINT)
- {
- gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Left operand %s is not an integer type.", gsk_sl_type_get_name (ltype));
- return NULL;
- }
- rscalar = gsk_sl_type_get_scalar_type (ltype);
- if (rscalar != GSK_SL_INT && rscalar != GSK_SL_UINT)
- {
- gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Right operand %s is not an integer type.", gsk_sl_type_get_name (rtype));
- return NULL;
- }
- if (!gsk_sl_type_is_scalar (ltype) && !gsk_sl_type_is_vector (ltype))
- {
- gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Left operand %s is neither a scalar nor a vector.", gsk_sl_type_get_name (ltype));
- return NULL;
- }
- if (!gsk_sl_type_is_scalar (rtype) && !gsk_sl_type_is_vector (rtype))
- {
- gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Right operand %s is neither a scalar nor a vector.", gsk_sl_type_get_name (rtype));
- return NULL;
- }
- if (gsk_sl_type_is_vector (ltype) && gsk_sl_type_is_vector (rtype) &&
- gsk_sl_type_get_length (ltype) != gsk_sl_type_get_length (rtype))
- {
- gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH,
- "Vector operands %s and %s do not have the same length.",
- gsk_sl_type_get_name (ltype), gsk_sl_type_get_name (rtype));
- return NULL;
- }
-
- rscalar = lscalar == GSK_SL_UINT ? GSK_SL_UINT : rscalar;
- if (gsk_sl_type_is_scalar (ltype) && gsk_sl_type_is_scalar (rtype))
- return gsk_sl_type_get_scalar (rscalar);
- else
- return gsk_sl_type_get_vector (rscalar, gsk_sl_type_get_length (ltype));
-}
-
-static GskSlType *
gsk_sl_shift_check_type (GskSlPreprocessor *preproc,
GskSlType *ltype,
GskSlType *rtype)
@@ -1931,13 +2058,6 @@ gsk_sl_unimplemented_write_spv (GskSpvWriter *writer,
return 0;
}
-static const GskSlBinary GSK_SL_BINARY_MODULO = {
- "%",
- gsk_sl_bitwise_check_type,
- gsk_sl_unimplemented_get_constant,
- gsk_sl_unimplemented_write_spv
-};
-
static const GskSlBinary GSK_SL_BINARY_LSHIFT = {
"<<",
gsk_sl_shift_check_type,