[gtk+/wip/otte/shader: 228/269] gskslexpression: Implement a logical and expression
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader: 228/269] gskslexpression: Implement a logical and expression
- Date: Tue, 24 Oct 2017 06:09:47 +0000 (UTC)
commit 7adffe8a23e503eb9ab8fb4e216f7ad686895e3d
Author: Benjamin Otte <otte redhat com>
Date: Thu Oct 12 02:38:03 2017 +0200
gskslexpression: Implement a logical and expression
This mirrors what we did for || - because the right side is not always
evaluated, this isn't a normal binary operation.
gsk/gskslexpression.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 125 insertions(+), 7 deletions(-)
---
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index 26d8c94..60c88ac 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -286,6 +286,126 @@ static const GskSlExpressionClass GSK_SL_EXPRESSION_BINARY = {
gsk_sl_expression_default_get_spv_access_chain
};
+/* LOGICAL_AND */
+
+typedef struct _GskSlExpressionLogicalAnd GskSlExpressionLogicalAnd;
+
+struct _GskSlExpressionLogicalAnd {
+ GskSlExpression parent;
+
+ GskSlExpression *left;
+ GskSlExpression *right;
+};
+
+static void
+gsk_sl_expression_logical_and_free (GskSlExpression *expression)
+{
+ GskSlExpressionLogicalAnd *logical_and = (GskSlExpressionLogicalAnd *) expression;
+
+ gsk_sl_expression_unref (logical_and->left);
+ gsk_sl_expression_unref (logical_and->right);
+
+ g_slice_free (GskSlExpressionLogicalAnd, logical_and);
+}
+
+static void
+gsk_sl_expression_logical_and_print (const GskSlExpression *expression,
+ GskSlPrinter *printer)
+{
+ GskSlExpressionLogicalAnd *logical_and = (GskSlExpressionLogicalAnd *) expression;
+
+ gsk_sl_expression_print (logical_and->left, printer);
+ gsk_sl_printer_append (printer, " && ");
+ gsk_sl_expression_print (logical_and->right, printer);
+}
+
+static GskSlType *
+gsk_sl_expression_logical_and_get_return_type (const GskSlExpression *expression)
+{
+ return gsk_sl_type_get_scalar (GSK_SL_BOOL);
+}
+
+static GskSlValue *
+gsk_sl_expression_logical_and_get_constant (const GskSlExpression *expression)
+{
+ const GskSlExpressionLogicalAnd *logical_and = (const GskSlExpressionLogicalAnd *) expression;
+ GskSlValue *lvalue, *rvalue;
+
+ lvalue = gsk_sl_expression_get_constant (logical_and->left);
+ if (lvalue == NULL)
+ return NULL;
+ rvalue = gsk_sl_expression_get_constant (logical_and->right);
+ if (rvalue == NULL)
+ {
+ gsk_sl_value_free (lvalue);
+ return NULL;
+ }
+
+ if (!(*(guint32 *) gsk_sl_value_get_data (lvalue)))
+ {
+ gsk_sl_value_free (rvalue);
+ return lvalue;
+ }
+ else
+ {
+ gsk_sl_value_free (lvalue);
+ return rvalue;
+ }
+}
+
+static guint32
+gsk_sl_expression_logical_and_write_spv (const GskSlExpression *expression,
+ GskSpvWriter *writer)
+{
+ const GskSlExpressionLogicalAnd *logical_and = (const GskSlExpressionLogicalAnd *) expression;
+ GskSpvCodeBlock *current_block, *after_block, *and_block;
+ guint32 current_id, after_id, and_id, left_id, right_id, result_id;
+
+ left_id = gsk_sl_expression_write_spv (logical_and->left, writer);
+
+ current_block = gsk_spv_writer_pop_code_block (writer);
+ current_id = gsk_spv_code_block_get_label (current_block);
+ gsk_spv_writer_push_code_block (writer, current_block);
+
+ and_id = gsk_spv_writer_push_new_code_block (writer);
+ and_block = gsk_spv_writer_pop_code_block (writer);
+
+ after_id = gsk_spv_writer_push_new_code_block (writer);
+ after_block = gsk_spv_writer_pop_code_block (writer);
+
+ /* mirror glslang */
+ gsk_spv_writer_selection_merge (writer, after_id, 0);
+ gsk_spv_writer_branch_conditional (writer, left_id, and_id, after_id, NULL, 0);
+
+ gsk_spv_writer_push_code_block (writer, and_block);
+ right_id = gsk_sl_expression_write_spv (logical_and->right, writer);
+ gsk_spv_writer_branch (writer, after_id);
+ gsk_spv_writer_commit_code_block (writer);
+
+ gsk_spv_writer_push_code_block (writer, after_block);
+ gsk_spv_writer_commit_code_block (writer);
+
+ result_id = gsk_spv_writer_phi (writer,
+ gsk_sl_type_get_scalar (GSK_SL_BOOL),
+ (guint32 **) (guint32[4][2]) {
+ { left_id, current_id },
+ { right_id, and_id }
+ },
+ 2);
+
+ return result_id;
+}
+
+static const GskSlExpressionClass GSK_SL_EXPRESSION_LOGICAL_AND = {
+ gsk_sl_expression_logical_and_free,
+ gsk_sl_expression_logical_and_print,
+ gsk_sl_expression_default_is_assignable,
+ gsk_sl_expression_logical_and_get_return_type,
+ gsk_sl_expression_logical_and_get_constant,
+ gsk_sl_expression_logical_and_write_spv,
+ gsk_sl_expression_default_get_spv_access_chain
+};
+
/* LOGICAL_OR */
typedef struct _GskSlExpressionLogicalOr GskSlExpressionLogicalOr;
@@ -2505,13 +2625,11 @@ gsk_sl_expression_parse_logical_and (GskSlScope *scope,
gsk_sl_expression_get_return_type (right));
if (result_type)
{
- GskSlExpressionBinary *binary_expr;
- binary_expr = gsk_sl_expression_new (GskSlExpressionBinary, &GSK_SL_EXPRESSION_BINARY);
- binary_expr->binary = binary;
- binary_expr->type = gsk_sl_type_ref (result_type);
- binary_expr->left = expression;
- binary_expr->right = right;
- expression = (GskSlExpression *) binary_expr;
+ GskSlExpressionLogicalAnd *logical_expr;
+ logical_expr = gsk_sl_expression_new (GskSlExpressionLogicalAnd, &GSK_SL_EXPRESSION_LOGICAL_AND);
+ logical_expr->left = expression;
+ logical_expr->right = right;
+ expression = (GskSlExpression *) logical_expr;
}
else
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]