[gtk+/wip/otte/shader: 254/269] gskslbinary: Implement equal and not equal operations
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader: 254/269] gskslbinary: Implement equal and not equal operations
- Date: Tue, 24 Oct 2017 06:11:59 +0000 (UTC)
commit a14b7800b14b5ca1db75d7b367108a4f36dc3174
Author: Benjamin Otte <otte redhat com>
Date: Sat Oct 21 21:38:38 2017 +0200
gskslbinary: Implement equal and not equal operations
gsk/gskslbinary.c | 332 ++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 290 insertions(+), 42 deletions(-)
---
diff --git a/gsk/gskslbinary.c b/gsk/gskslbinary.c
index 7486d7d..5d5f7cf 100644
--- a/gsk/gskslbinary.c
+++ b/gsk/gskslbinary.c
@@ -1497,6 +1497,296 @@ static const GskSlBinary GSK_SL_BINARY_GREATER_EQUAL = {
gsk_sl_greater_equal_write_spv
};
+/* EQUAL */
+
+static GskSlType *
+gsk_sl_equal_check_type (GskSlPreprocessor *preproc,
+ GskSlType *ltype,
+ GskSlType *rtype)
+{
+ if (gsk_sl_type_contains_opaque (ltype))
+ {
+ gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Cannot do equality conversion with opaque type
%s.",
+ gsk_sl_type_get_name (ltype));
+ return NULL;
+ }
+ if (gsk_sl_type_contains_opaque (rtype))
+ {
+ gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Cannot do equality conversion with opaque type
%s.",
+ gsk_sl_type_get_name (rtype));
+ return NULL;
+ }
+
+ if (gsk_sl_type_can_convert (ltype, rtype))
+ return gsk_sl_type_get_scalar (GSK_SL_BOOL);
+ if (gsk_sl_type_can_convert (rtype, ltype))
+ return gsk_sl_type_get_scalar (GSK_SL_BOOL);
+
+ gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Cannot convert %s and %s to the same type for
comparison.",
+ gsk_sl_type_get_name (ltype), gsk_sl_type_get_name (rtype));
+ return NULL;
+}
+
+static guint32
+gsk_sl_equal_generic_scalar_write_spv (GskSpvWriter *writer,
+ gboolean equality,
+ GskSlType *result_type,
+ GskSlScalarType scalar,
+ guint32 left_id,
+ guint32 right_id)
+{
+ switch (scalar)
+ {
+ case GSK_SL_FLOAT:
+ case GSK_SL_DOUBLE:
+ if (equality)
+ return gsk_spv_writer_f_ord_equal (writer, result_type, left_id, right_id);
+ else
+ return gsk_spv_writer_f_ord_not_equal (writer, result_type, left_id, right_id);
+
+ case GSK_SL_INT:
+ case GSK_SL_UINT:
+ if (equality)
+ return gsk_spv_writer_i_equal (writer, result_type, left_id, right_id);
+ else
+ return gsk_spv_writer_i_not_equal (writer, result_type, left_id, right_id);
+
+ case GSK_SL_BOOL:
+ if (equality)
+ return gsk_spv_writer_logical_equal (writer, result_type, left_id, right_id);
+ else
+ return gsk_spv_writer_logical_not_equal (writer, result_type, left_id, right_id);
+
+ case GSK_SL_VOID:
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+static guint32
+gsk_sl_equal_generic_write_spv (GskSpvWriter *writer,
+ gboolean equality,
+ GskSlType *type,
+ guint32 left_id,
+ guint32 right_id)
+{
+ GskSlType *bool_type = gsk_sl_type_get_scalar (GSK_SL_BOOL);
+
+ if (gsk_sl_type_is_scalar (type))
+ {
+ return gsk_sl_equal_generic_scalar_write_spv (writer,
+ equality,
+ bool_type,
+ gsk_sl_type_get_scalar_type (type),
+ left_id,
+ right_id);
+ }
+ else if (gsk_sl_type_is_vector (type))
+ {
+ guint tmp_id;
+
+ tmp_id = gsk_sl_equal_generic_scalar_write_spv (writer,
+ equality,
+ gsk_sl_type_get_vector (GSK_SL_BOOL,
+ gsk_sl_type_get_length (type)),
+ gsk_sl_type_get_scalar_type (type),
+ left_id,
+ right_id);
+ if (equality)
+ return gsk_spv_writer_all (writer, bool_type, tmp_id);
+ else
+ return gsk_spv_writer_any (writer, bool_type, tmp_id);
+ }
+ else if (gsk_sl_type_get_length (type))
+ {
+ /* matrices and arrays */
+ GskSlType *index_type;
+ guint32 left_part_id, right_part_id, tmp_id, result_id;
+ gsize i, n;
+
+ n = gsk_sl_type_get_length (type);
+ index_type = gsk_sl_type_get_index_type (type);
+
+ for (i = 0; i < n; i++)
+ {
+ left_part_id = gsk_spv_writer_composite_extract (writer,
+ index_type,
+ left_id,
+ (guint32[1]) { i }, 1);
+ right_part_id = gsk_spv_writer_composite_extract (writer,
+ index_type,
+ right_id,
+ (guint32[1]) { i }, 1);
+ tmp_id = gsk_sl_equal_generic_write_spv (writer,
+ equality,
+ index_type,
+ left_part_id,
+ right_part_id);
+ if (i == 0)
+ result_id = tmp_id;
+ else if (equality)
+ result_id = gsk_spv_writer_logical_and (writer, bool_type, result_id, tmp_id);
+ else
+ result_id = gsk_spv_writer_logical_or (writer, bool_type, result_id, tmp_id);
+ }
+
+ return result_id;
+ }
+ else
+ {
+ /* structs and blocks */
+ guint32 left_part_id, right_part_id, tmp_id, result_id;
+ gsize n_members, i;
+
+ n_members = gsk_sl_type_get_n_members (type);
+ g_assert (n_members > 0);
+
+ for (i = 0; i < n_members; i++)
+ {
+ GskSlType *member_type = gsk_sl_type_get_member_type (type, i);
+
+ left_part_id = gsk_spv_writer_composite_extract (writer,
+ member_type,
+ left_id,
+ (guint32[1]) { i }, 1);
+ right_part_id = gsk_spv_writer_composite_extract (writer,
+ member_type,
+ right_id,
+ (guint32[1]) { i }, 1);
+ tmp_id = gsk_sl_equal_generic_write_spv (writer,
+ equality,
+ member_type,
+ left_part_id,
+ right_part_id);
+ if (i == 0)
+ result_id = tmp_id;
+ else if (equality)
+ result_id = gsk_spv_writer_logical_and (writer, bool_type, result_id, tmp_id);
+ else
+ result_id = gsk_spv_writer_logical_or (writer, bool_type, result_id, tmp_id);
+ }
+
+ return result_id;
+ }
+}
+
+static GskSlValue *
+gsk_sl_equal_get_constant (GskSlType *type,
+ GskSlValue *lvalue,
+ GskSlValue *rvalue)
+{
+ GskSlValue *result;
+
+ if (gsk_sl_type_equal (gsk_sl_value_get_type (lvalue), gsk_sl_value_get_type (rvalue)))
+ {
+ /* weee.... */
+ }
+ else if (gsk_sl_type_can_convert (gsk_sl_value_get_type (lvalue), gsk_sl_value_get_type (rvalue)))
+ {
+ GskSlValue *tmp = gsk_sl_value_new_convert (lvalue, gsk_sl_value_get_type (rvalue));
+ gsk_sl_value_free (lvalue);
+ lvalue = tmp;
+ }
+ else
+ {
+ GskSlValue *tmp = gsk_sl_value_new_convert (rvalue, gsk_sl_value_get_type (lvalue));
+ gsk_sl_value_free (rvalue);
+ rvalue = tmp;
+ }
+
+ result = gsk_sl_value_new (type);
+ *(guint32 *) gsk_sl_value_get_data (result) = gsk_sl_value_equal (lvalue, rvalue);
+ return result;
+}
+
+static guint32
+gsk_sl_equal_write_spv (GskSpvWriter *writer,
+ GskSlType *type,
+ GskSlType *ltype,
+ guint32 left_id,
+ GskSlType *rtype,
+ guint32 right_id)
+{
+ if (gsk_sl_type_can_convert (ltype, rtype))
+ {
+ right_id = gsk_spv_writer_convert (writer, right_id, rtype, ltype);
+ rtype = ltype;
+ }
+ else
+ {
+ left_id = gsk_spv_writer_convert (writer, left_id, ltype, rtype);
+ ltype = rtype;
+ }
+
+ return gsk_sl_equal_generic_write_spv (writer, TRUE, ltype, left_id, right_id);
+}
+
+static GskSlValue *
+gsk_sl_not_equal_get_constant (GskSlType *type,
+ GskSlValue *lvalue,
+ GskSlValue *rvalue)
+{
+ GskSlValue *result;
+
+ if (gsk_sl_type_equal (gsk_sl_value_get_type (lvalue), gsk_sl_value_get_type (rvalue)))
+ {
+ /* weee.... */
+ }
+ else if (gsk_sl_type_can_convert (gsk_sl_value_get_type (lvalue), gsk_sl_value_get_type (rvalue)))
+ {
+ GskSlValue *tmp = gsk_sl_value_new_convert (lvalue, gsk_sl_value_get_type (rvalue));
+ gsk_sl_value_free (lvalue);
+ lvalue = tmp;
+ }
+ else
+ {
+ GskSlValue *tmp = gsk_sl_value_new_convert (rvalue, gsk_sl_value_get_type (lvalue));
+ gsk_sl_value_free (rvalue);
+ rvalue = tmp;
+ }
+
+ result = gsk_sl_value_new (type);
+ *(guint32 *) gsk_sl_value_get_data (result) = !gsk_sl_value_equal (lvalue, rvalue);
+ return result;
+}
+
+static guint32
+gsk_sl_not_equal_write_spv (GskSpvWriter *writer,
+ GskSlType *type,
+ GskSlType *ltype,
+ guint32 left_id,
+ GskSlType *rtype,
+ guint32 right_id)
+{
+ if (gsk_sl_type_can_convert (ltype, rtype))
+ {
+ right_id = gsk_spv_writer_convert (writer, right_id, rtype, ltype);
+ rtype = ltype;
+ }
+ else
+ {
+ left_id = gsk_spv_writer_convert (writer, left_id, ltype, rtype);
+ ltype = rtype;
+ }
+
+ return gsk_sl_equal_generic_write_spv (writer, FALSE, ltype, left_id, right_id);
+}
+
+static const GskSlBinary GSK_SL_BINARY_EQUAL = {
+ "==",
+ gsk_sl_equal_check_type,
+ gsk_sl_equal_get_constant,
+ gsk_sl_equal_write_spv
+};
+
+static const GskSlBinary GSK_SL_BINARY_NOT_EQUAL = {
+ "!=",
+ gsk_sl_equal_check_type,
+ gsk_sl_not_equal_get_constant,
+ gsk_sl_not_equal_write_spv
+};
+
/* UNIMPLEMENTED */
static GskSlType *
@@ -1594,34 +1884,6 @@ gsk_sl_shift_check_type (GskSlPreprocessor *preproc,
}
static GskSlType *
-gsk_sl_equal_check_type (GskSlPreprocessor *preproc,
- GskSlType *ltype,
- GskSlType *rtype)
-{
- if (gsk_sl_type_contains_opaque (ltype))
- {
- gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Cannot do equality conversion with opaque type
%s.",
- gsk_sl_type_get_name (ltype));
- return NULL;
- }
- if (gsk_sl_type_contains_opaque (rtype))
- {
- gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Cannot do equality conversion with opaque type
%s.",
- gsk_sl_type_get_name (rtype));
- return NULL;
- }
-
- if (gsk_sl_type_can_convert (ltype, rtype))
- return gsk_sl_type_get_scalar (GSK_SL_BOOL);
- if (gsk_sl_type_can_convert (rtype, ltype))
- return gsk_sl_type_get_scalar (GSK_SL_BOOL);
-
- gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Cannot convert %s and %s to the same type for
comparison.",
- gsk_sl_type_get_name (ltype), gsk_sl_type_get_name (rtype));
- return NULL;
-}
-
-static GskSlType *
gsk_sl_logical_check_type (GskSlPreprocessor *preproc,
GskSlType *ltype,
GskSlType *rtype)
@@ -1690,20 +1952,6 @@ static const GskSlBinary GSK_SL_BINARY_RSHIFT = {
gsk_sl_unimplemented_write_spv
};
-static const GskSlBinary GSK_SL_BINARY_EQUAL = {
- "==",
- gsk_sl_equal_check_type,
- gsk_sl_unimplemented_get_constant,
- gsk_sl_unimplemented_write_spv
-};
-
-static const GskSlBinary GSK_SL_BINARY_NOT_EQUAL = {
- "!=",
- gsk_sl_equal_check_type,
- gsk_sl_unimplemented_get_constant,
- gsk_sl_unimplemented_write_spv
-};
-
static const GskSlBinary GSK_SL_BINARY_AND = {
"&",
gsk_sl_bitwise_check_type,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]