diff options
author | Benjamin Otte <otte@redhat.com> | 2017-10-18 05:40:40 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2017-10-30 02:58:03 +0100 |
commit | 516cd4b4993b206eae31fbf4a08e204d50ad08d2 (patch) | |
tree | 8fe664a03d66bf3c1986b16d5c36ff1e7fa5a9a3 | |
parent | 38a255d13270dc108bc700cb0434a27070048674 (diff) | |
download | gtk+-516cd4b4993b206eae31fbf4a08e204d50ad08d2.tar.gz |
gsksltype: Add sampler types
Also add texture() and texelFetch() functions and all variants.
textureGather() and textureQuery() functions are still missing
-rw-r--r-- | gsk/gskslimagetype.c | 268 | ||||
-rw-r--r-- | gsk/gskslimagetypeprivate.h | 65 | ||||
-rw-r--r-- | gsk/gskslnativefunction.c | 452 | ||||
-rw-r--r-- | gsk/gskslstatement.c | 40 | ||||
-rw-r--r-- | gsk/gsksltype.c | 375 | ||||
-rw-r--r-- | gsk/gsksltypeprivate.h | 3 | ||||
-rw-r--r-- | gsk/gsksltypesprivate.h | 45 | ||||
-rw-r--r-- | gsk/gskspvwriter.c | 38 | ||||
-rw-r--r-- | gsk/gskspvwriterprivate.h | 4 | ||||
-rw-r--r-- | gsk/meson.build | 1 |
10 files changed, 1290 insertions, 1 deletions
diff --git a/gsk/gskslimagetype.c b/gsk/gskslimagetype.c new file mode 100644 index 0000000000..2f8056c370 --- /dev/null +++ b/gsk/gskslimagetype.c @@ -0,0 +1,268 @@ +/* GTK - The GIMP Toolkit + * + * Copyright © 2017 Benjamin Otte <otte@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include "gskslimagetypeprivate.h" + +#include "gsksltypeprivate.h" +#include "gskspvwriterprivate.h" + +gboolean +gsk_sl_image_type_supports_projection (const GskSlImageType *type, + gboolean extra_dim) +{ + if (type->arrayed) + return FALSE; + + if (type->multisampled) + return FALSE; + + if (extra_dim && type->shadow) + return FALSE; + + switch (type->dim) + { + case GSK_SPV_DIM_1_D: + case GSK_SPV_DIM_2_D: + case GSK_SPV_DIM_RECT: + return TRUE; + case GSK_SPV_DIM_3_D: + return !extra_dim; + case GSK_SPV_DIM_CUBE: + case GSK_SPV_DIM_BUFFER: + case GSK_SPV_DIM_SUBPASS_DATA: + default: + return FALSE; + } +} + +gboolean +gsk_sl_image_type_supports_lod (const GskSlImageType *type) +{ + if (type->multisampled) + return FALSE; + + switch (type->dim) + { + case GSK_SPV_DIM_1_D: + return TRUE; + case GSK_SPV_DIM_2_D: + case GSK_SPV_DIM_3_D: + return !type->arrayed || !type->shadow; + case GSK_SPV_DIM_CUBE: + return !type->shadow; + case GSK_SPV_DIM_RECT: + case GSK_SPV_DIM_BUFFER: + case GSK_SPV_DIM_SUBPASS_DATA: + default: + return FALSE; + } +} + +gboolean +gsk_sl_image_type_supports_bias (const GskSlImageType *type) +{ + if (type->multisampled) + return FALSE; + + switch (type->dim) + { + case GSK_SPV_DIM_1_D: + case GSK_SPV_DIM_3_D: + case GSK_SPV_DIM_CUBE: + return TRUE; + case GSK_SPV_DIM_2_D: + return !type->arrayed || !type->shadow; + case GSK_SPV_DIM_RECT: + case GSK_SPV_DIM_BUFFER: + case GSK_SPV_DIM_SUBPASS_DATA: + default: + return FALSE; + } +} + +gboolean +gsk_sl_image_type_supports_offset (const GskSlImageType *type) +{ + if (type->multisampled) + return FALSE; + + switch (type->dim) + { + case GSK_SPV_DIM_1_D: + case GSK_SPV_DIM_2_D: + case GSK_SPV_DIM_3_D: + case GSK_SPV_DIM_RECT: + return TRUE; + case GSK_SPV_DIM_CUBE: + case GSK_SPV_DIM_BUFFER: + case GSK_SPV_DIM_SUBPASS_DATA: + default: + return FALSE; + } +} + +gboolean +gsk_sl_image_type_supports_gradient (const GskSlImageType *type) +{ + if (type->multisampled) + return FALSE; + + if (type->dim == GSK_SPV_DIM_BUFFER) + return FALSE; + + return TRUE; +} + +gboolean +gsk_sl_image_type_supports_texel_fetch (const GskSlImageType *type) +{ + if (type->shadow) + return FALSE; + + if (type->dim == GSK_SPV_DIM_CUBE) + return FALSE; + + return TRUE; +} + +gboolean +gsk_sl_image_type_supports_texture (const GskSlImageType *type) +{ + if (type->multisampled) + return FALSE; + + if (type->dim == GSK_SPV_DIM_BUFFER) + return FALSE; + + return TRUE; +} + +gboolean +gsk_sl_image_type_needs_lod_argument (const GskSlImageType *type, + gboolean texel_fetch) +{ + if (type->multisampled) + return TRUE; + + return type->dim != GSK_SPV_DIM_RECT + && type->dim != GSK_SPV_DIM_BUFFER; +} + +guint +gsk_sl_image_type_get_dimensions (const GskSlImageType *type) +{ + switch (type->dim) + { + case GSK_SPV_DIM_1_D: + case GSK_SPV_DIM_BUFFER: + return 1; + + case GSK_SPV_DIM_2_D: + case GSK_SPV_DIM_RECT: + case GSK_SPV_DIM_SUBPASS_DATA: + return 2; + + case GSK_SPV_DIM_3_D: + case GSK_SPV_DIM_CUBE: + return 3; + + default: + g_assert_not_reached (); + return 1; + } +} + +guint +gsk_sl_image_type_get_lookup_dimensions (const GskSlImageType *type, + gboolean projection) +{ + guint result = gsk_sl_image_type_get_dimensions (type); + + if (type->arrayed) + result++; + + if (type->shadow) + { + /* because GLSL is GLSL */ + result = MAX (result, 2); + result++; + } + + if (projection) + result++; + + return result; +} + +GskSlType * +gsk_sl_image_type_get_pixel_type (const GskSlImageType *type) +{ + if (type->shadow) + return gsk_sl_type_get_scalar (type->sampled_type); + else + return gsk_sl_type_get_vector (type->sampled_type, 4); +} + +guint32 +gsk_sl_image_type_write_spv (const GskSlImageType *type, + GskSpvWriter *writer) +{ + guint32 sampled_type_id; + + sampled_type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_scalar (type->sampled_type)); + return gsk_spv_writer_type_image (writer, + sampled_type_id, + type->dim, + type->shadow, + type->arrayed, + type->multisampled, + 2 - type->sampler, + GSK_SPV_IMAGE_FORMAT_UNKNOWN, + -1); +} + +guint +gsk_sl_image_type_hash (gconstpointer type) +{ + const GskSlImageType *image = type; + + return image->sampled_type + | (image->dim << 8) + | (image->shadow << 16) + | (image->arrayed << 17) + | (image->multisampled << 18) + | (image->sampler << 19); +} + +gboolean +gsk_sl_image_type_equal (gconstpointer a, + gconstpointer b) +{ + const GskSlImageType *ia = a; + const GskSlImageType *ib = b; + + return ia->sampled_type == ib->sampled_type + && ia->dim == ib->dim + && ia->shadow == ib->shadow + && ia->arrayed == ib->arrayed + && ia->multisampled == ib->multisampled + && ia->sampler == ib->sampler; +} + diff --git a/gsk/gskslimagetypeprivate.h b/gsk/gskslimagetypeprivate.h new file mode 100644 index 0000000000..0e81025b78 --- /dev/null +++ b/gsk/gskslimagetypeprivate.h @@ -0,0 +1,65 @@ +/* GTK - The GIMP Toolkit + * + * Copyright © 2017 Benjamin Otte <otte@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __GSK_SL_IMAGE_TYPE_PRIVATE_H__ +#define __GSK_SL_IMAGE_TYPE_PRIVATE_H__ + +#include <glib.h> + +#include "gsksltypesprivate.h" +#include "gskspvenumsprivate.h" + +G_BEGIN_DECLS + +struct _GskSlImageType +{ + GskSlScalarType sampled_type; + GskSpvDim dim; + guint shadow :1; + guint arrayed :1; + guint multisampled :1; + guint sampler :1; +}; + +gboolean gsk_sl_image_type_supports_projection (const GskSlImageType *type, + gboolean extra_dim); +gboolean gsk_sl_image_type_supports_lod (const GskSlImageType *type); +gboolean gsk_sl_image_type_supports_bias (const GskSlImageType *type); +gboolean gsk_sl_image_type_supports_offset (const GskSlImageType *type); +gboolean gsk_sl_image_type_supports_gradient (const GskSlImageType *type); +gboolean gsk_sl_image_type_supports_texture (const GskSlImageType *type); +gboolean gsk_sl_image_type_supports_texel_fetch (const GskSlImageType *type); +gboolean gsk_sl_image_type_needs_lod_argument (const GskSlImageType *type, + gboolean texel_fetch); + +guint gsk_sl_image_type_get_dimensions (const GskSlImageType *type); +guint gsk_sl_image_type_get_lookup_dimensions (const GskSlImageType *type, + gboolean projection); + +GskSlType * gsk_sl_image_type_get_pixel_type (const GskSlImageType *type); + +guint32 gsk_sl_image_type_write_spv (const GskSlImageType *type, + GskSpvWriter *writer); + +guint gsk_sl_image_type_hash (gconstpointer type); +gboolean gsk_sl_image_type_equal (gconstpointer a, + gconstpointer b); + +G_END_DECLS + +#endif /* __GSK_SL_IMAGE_TYPE_PRIVATE_H__ */ diff --git a/gsk/gskslnativefunction.c b/gsk/gskslnativefunction.c index 168867d302..f759c9a694 100644 --- a/gsk/gskslnativefunction.c +++ b/gsk/gskslnativefunction.c @@ -21,6 +21,7 @@ #include "gskslnativefunctionprivate.h" #include "gskslenvironmentprivate.h" +#include "gskslimagetypeprivate.h" #include "gskslfunctionprivate.h" #include "gskslfunctiontypeprivate.h" #include "gskslscopeprivate.h" @@ -1355,6 +1356,455 @@ gsk_sl_native_functions_add_150 (GskSlScope *scope, UNIMPLEMENTED_NATIVE1 (MAT4, inverse, MAT4); } +#define PACK_TEXTURE_CALL_INFO(types, proj, lod, bias, offset, fetch, grad) \ + GUINT_TO_POINTER(((types) & 0xFF) | ((proj) << 16) | ((lod) << 18) | ((bias) << 19) | ((offset) << 20) | ((fetch) << 21) | ((grad) << 22)) +#define UNPACK_TEXTURE_CALL_INFO(_info, type, proj, lod, bias, offset, fetch, grad) G_STMT_START{\ + guint info = GPOINTER_TO_UINT(_info); \ +\ + type = info & 0xFF; \ + proj = (info >> 16) & 0x3; \ + lod = (info >> 18) & 0x1; \ + bias = (info >> 19) & 0x1; \ + offset = (info >> 20) & 0x1; \ + fetch = (info >> 21) & 0x1; \ + grad = (info >> 22) & 0x1; \ +}G_STMT_END + +static guint32 +gsk_sl_native_texture_write_spv (GskSpvWriter *writer, + guint32 *arguments, + gpointer user_data) +{ + guint types, proj, lod, bias, offset, fetch, grad, dref, min_lod; + const GskSlImageType *image; + GskSlType *type; + guint32 extra_args[9], n_extra_args; + guint32 mask; + guint length; + gboolean explicit_lod = FALSE; + gsize i; + + UNPACK_TEXTURE_CALL_INFO(user_data, types, proj, lod, bias, offset, fetch, grad); + type = gsk_sl_type_get_sampler (types); + image = gsk_sl_type_get_image_type (type); + length = gsk_sl_image_type_get_lookup_dimensions (image, proj > 0); + mask = 0; + n_extra_args = 0; + i = 2; + + if (fetch && gsk_sl_image_type_needs_lod_argument (image, fetch)) + min_lod = i++; + else + min_lod = 0; + + /* match used flags to their argument number */ + if (lod) + lod = i++; + if (grad) + { + grad = i; + i += 2; + } + if (offset) + offset = i++; + if (length > 4) + dref = arguments[i++]; + else if (image->shadow) + { + dref = gsk_spv_writer_composite_extract (writer, + gsk_sl_type_get_scalar (GSK_SL_FLOAT), + arguments[1], + (guint32[1]) { length - 1 - (proj ? 1 : 0) }, + 1); + } + else + dref = 0; + if (proj) + { + guint real_length = (proj == 2 ? 4 : MIN (4, length)); + + if (real_length != gsk_sl_image_type_get_dimensions (image) + 1) + { + guint32 tmp_id; + + tmp_id = gsk_spv_writer_composite_extract (writer, + gsk_sl_type_get_scalar (GSK_SL_FLOAT), + arguments[1], + (guint32[1]) { real_length - 1 }, + 1); + arguments[1] = gsk_spv_writer_composite_insert (writer, + gsk_sl_type_get_vector (GSK_SL_FLOAT, real_length), + tmp_id, + arguments[1], + (guint32[1]) { gsk_sl_image_type_get_dimensions (image) }, + 1); + } + } + + if (bias) + bias = i++; + + if (bias) + { + mask |= GSK_SPV_IMAGE_OPERANDS_BIAS; + extra_args[n_extra_args++] = arguments[bias]; + } + if (lod) + { + mask |= GSK_SPV_IMAGE_OPERANDS_LOD; + extra_args[n_extra_args++] = arguments[lod]; + explicit_lod = TRUE; + } + if (min_lod && !image->multisampled) + { + g_assert (!lod); + mask |= GSK_SPV_IMAGE_OPERANDS_LOD; + extra_args[n_extra_args++] = arguments[min_lod]; + } + + if (grad) + { + mask |= GSK_SPV_IMAGE_OPERANDS_GRAD; + extra_args[n_extra_args++] = arguments[grad]; + extra_args[n_extra_args++] = arguments[grad + 1]; + explicit_lod = TRUE; + } + if (offset) + { + if (gsk_spv_writer_get_value_for_id (writer, arguments[offset])) + mask |= GSK_SPV_IMAGE_OPERANDS_CONST_OFFSET; + else + mask |= GSK_SPV_IMAGE_OPERANDS_OFFSET; + extra_args[n_extra_args++] = arguments[offset]; + } + if (min_lod && image->multisampled) + { + mask |= GSK_SPV_IMAGE_OPERANDS_SAMPLE; + extra_args[n_extra_args++] = arguments[min_lod]; + } + + if (fetch) + { + guint32 image_id; + + image_id = gsk_spv_writer_image (writer, + gsk_spv_writer_get_id_for_image_type (writer, image), + arguments[0]); + + return gsk_spv_writer_image_fetch (writer, + gsk_sl_image_type_get_pixel_type (image), + image_id, + arguments[1], + mask, + extra_args, + n_extra_args); + } + else if (explicit_lod) + { + if (dref) + { + if (proj) + { + return gsk_spv_writer_image_sample_proj_dref_explicit_lod (writer, + gsk_sl_image_type_get_pixel_type (image), + arguments[0], + arguments[1], + dref, + mask, + extra_args, + n_extra_args); + } + else + { + return gsk_spv_writer_image_sample_dref_explicit_lod (writer, + gsk_sl_image_type_get_pixel_type (image), + arguments[0], + arguments[1], + dref, + mask, + extra_args, + n_extra_args); + } + } + else + { + if (proj) + { + return gsk_spv_writer_image_sample_proj_explicit_lod (writer, + gsk_sl_image_type_get_pixel_type (image), + arguments[0], + arguments[1], + mask, + extra_args, + n_extra_args); + } + else + { + return gsk_spv_writer_image_sample_explicit_lod (writer, + gsk_sl_image_type_get_pixel_type (image), + arguments[0], + arguments[1], + mask, + extra_args, + n_extra_args); + } + } + } + else + { + if (dref) + { + if (proj) + { + return gsk_spv_writer_image_sample_proj_dref_implicit_lod (writer, + gsk_sl_image_type_get_pixel_type (image), + arguments[0], + arguments[1], + dref, + mask, + extra_args, + n_extra_args); + } + else + { + return gsk_spv_writer_image_sample_dref_implicit_lod (writer, + gsk_sl_image_type_get_pixel_type (image), + arguments[0], + arguments[1], + dref, + mask, + extra_args, + n_extra_args); + } + } + else + { + if (proj) + { + return gsk_spv_writer_image_sample_proj_implicit_lod (writer, + gsk_sl_image_type_get_pixel_type (image), + arguments[0], + arguments[1], + mask, + extra_args, + n_extra_args); + } + else + { + return gsk_spv_writer_image_sample_implicit_lod (writer, + gsk_sl_image_type_get_pixel_type (image), + arguments[0], + arguments[1], + mask, + extra_args, + n_extra_args); + } + } + } +} + +static void +gsk_sl_native_functions_add_texture (GskSlScope *scope, + GskSlEnvironment *environment) +{ + GskSlType *type; + const GskSlImageType *image; + guint types, proj, lod, bias, offset, fetch, grad; + + for (types = 0; types < GSK_SL_N_SAMPLER_TYPES; types++) + { + type = gsk_sl_type_get_sampler (types); + image = gsk_sl_type_get_image_type (type); + + for (proj = 0; proj < 3; proj++) + { + if (proj && !gsk_sl_image_type_supports_projection (image, proj == 2)) + continue; + + for (lod = 0; lod < 2; lod++) + { + if (lod && !gsk_sl_image_type_supports_lod (image)) + continue; + + for (bias = 0; bias < 2; bias++) + { + if (bias && lod) + continue; + + if (bias && gsk_sl_environment_get_stage (environment) != GSK_SL_SHADER_FRAGMENT) + continue; + + if (bias && !gsk_sl_image_type_supports_bias (image)) + continue; + + for (offset = 0; offset < 2; offset++) + { + if (offset && !gsk_sl_image_type_supports_offset (image)) + continue; + + for (fetch = 0; fetch < 2; fetch++) + { + if ((proj > 0) + offset + fetch + bias + lod > 3) + continue; + if (fetch && (lod || bias)) + continue; + if (fetch && !gsk_sl_image_type_supports_texel_fetch (image)) + continue; + if (!fetch && !gsk_sl_image_type_supports_texture (image)) + continue; + + for (grad = 0; grad < 2; grad++) + { + GskSlFunction *function; + GskSlFunctionType *function_type; + char *function_name; + guint length; + + if ((proj > 0) + offset + fetch + grad + bias + lod > 3) + continue; + + if (grad && (lod || bias)) + continue; + + if (grad && !gsk_sl_image_type_supports_gradient (image)) + continue; + + length = gsk_sl_image_type_get_lookup_dimensions (image, proj > 0); + if (length > 4 && bias) + continue; + + function_type = gsk_sl_function_type_new (gsk_sl_image_type_get_pixel_type (image)); + function_type = gsk_sl_function_type_add_argument (function_type, + GSK_SL_STORAGE_PARAMETER_IN, + type); + + /* P */ + if (proj == 2) + { + function_type = gsk_sl_function_type_add_argument (function_type, + GSK_SL_STORAGE_PARAMETER_IN, + gsk_sl_type_get_vector (GSK_SL_FLOAT, 4)); + } + else + { + GskSlScalarType scalar; + GskSlType *arg_type; + + scalar = fetch ? GSK_SL_INT : GSK_SL_FLOAT; + if (length == 1) + arg_type = gsk_sl_type_get_scalar (scalar); + else + arg_type = gsk_sl_type_get_vector (scalar, MIN (length, 4)); + function_type = gsk_sl_function_type_add_argument (function_type, + GSK_SL_STORAGE_PARAMETER_IN, + arg_type); + } + + /* non-optional lod */ + if (fetch && gsk_sl_image_type_needs_lod_argument (image, fetch)) + function_type = gsk_sl_function_type_add_argument (function_type, + GSK_SL_STORAGE_PARAMETER_IN, + gsk_sl_type_get_scalar (GSK_SL_INT)); + + if (lod) + function_type = gsk_sl_function_type_add_argument (function_type, + GSK_SL_STORAGE_PARAMETER_IN, + gsk_sl_type_get_scalar (GSK_SL_FLOAT)); + + if (grad) + { + GskSlType *arg_type; + guint dims = gsk_sl_image_type_get_dimensions (image); + + if (dims ==1) + arg_type = gsk_sl_type_get_scalar (GSK_SL_FLOAT); + else + arg_type = gsk_sl_type_get_vector (GSK_SL_FLOAT, dims); + + function_type = gsk_sl_function_type_add_argument (function_type, + GSK_SL_STORAGE_PARAMETER_IN, + arg_type); + function_type = gsk_sl_function_type_add_argument (function_type, + GSK_SL_STORAGE_PARAMETER_IN, + arg_type); + } + + if (offset) + { + GskSlType *arg_type; + guint dims = gsk_sl_image_type_get_dimensions (image); + + if (dims ==1) + arg_type = gsk_sl_type_get_scalar (GSK_SL_INT); + else + arg_type = gsk_sl_type_get_vector (GSK_SL_INT, dims); + + function_type = gsk_sl_function_type_add_argument (function_type, + GSK_SL_STORAGE_PARAMETER_IN, + arg_type); + } + + /* compare */ + if (length > 4) + function_type = gsk_sl_function_type_add_argument (function_type, + GSK_SL_STORAGE_PARAMETER_IN, + gsk_sl_type_get_scalar (GSK_SL_FLOAT)); + + if (bias) + function_type = gsk_sl_function_type_add_argument (function_type, + GSK_SL_STORAGE_PARAMETER_IN, + gsk_sl_type_get_scalar (GSK_SL_FLOAT)); + + function_name = g_strconcat (fetch ? "texel" : "texture", + proj ? "Proj" : "", + lod ? "Lod" : "", + grad ? "Grad" : "", + fetch ? "Fetch" : "", + offset ? "Offset" : "", + NULL); + + function = gsk_sl_function_new_native (function_name, + function_type, + NULL, + gsk_sl_native_texture_write_spv, + PACK_TEXTURE_CALL_INFO (types, proj, lod, bias, offset, fetch, grad), + NULL); + gsk_sl_scope_add_function (scope, function); +#if 0 + g_print ("%p %p %p %p %p %p %p %u %u\n", PACK_TEXTURE_CALL_INFO (types, proj, lod, bias, offset, fetch, grad), + GUINT_TO_POINTER(((types) & 0xFF) | ((proj) << 16) | ((lod) << 18) | ((bias) < 19) | ((offset) << 20) | ((fetch) << 21)), + GUINT_TO_POINTER(((types) & 0xFF) | ((proj) << 16) | ((lod) << 18) | ((bias) < 19) | ((offset) << 20)), + GUINT_TO_POINTER(((types) & 0xFF) | ((proj) << 16) | ((lod) << 18) | ((bias) < 19)), + GUINT_TO_POINTER(((types) & 0xFF) | ((proj) << 16) | ((lod) << 18)), + GUINT_TO_POINTER(((types) & 0xFF) | ((proj) << 16)), + GUINT_TO_POINTER(((types) & 0xFF) ), types, (types) & 0xFF); + g_print ("%u %u %u %u %u %u %u\n", types, proj, lod, bias, offset, fetch, grad); + { + guint i; + g_print ("%s", gsk_sl_type_get_name (gsk_sl_function_type_get_return_type (function_type))); + g_print (" %s(", function_name); + for (i = 0; i < gsk_sl_function_type_get_n_arguments (function_type); i++) + { + if (i > 0) + g_print (","); + g_print ("%s", gsk_sl_type_get_name (gsk_sl_function_type_get_argument_type (function_type, i))); + } + g_print (");\n"); + } +#endif + + g_free (function_name); + gsk_sl_function_unref (function); + gsk_sl_function_type_unref (function_type); + } + } + } + } + } + } + } +} + void gsk_sl_native_functions_add (GskSlScope *scope, GskSlEnvironment *environment) @@ -1374,5 +1824,7 @@ gsk_sl_native_functions_add (GskSlScope *scope, if (version < 150) return; gsk_sl_native_functions_add_150 (scope, environment); + + gsk_sl_native_functions_add_texture (scope, environment); } diff --git a/gsk/gskslstatement.c b/gsk/gskslstatement.c index 4fdb31788b..27e605fb67 100644 --- a/gsk/gskslstatement.c +++ b/gsk/gskslstatement.c @@ -973,6 +973,46 @@ gsk_sl_statement_parse (GskSlScope *scope, case GSK_SL_TOKEN_DMAT4X2: case GSK_SL_TOKEN_DMAT4X3: case GSK_SL_TOKEN_DMAT4X4: + case GSK_SL_TOKEN_SAMPLER1D: + case GSK_SL_TOKEN_SAMPLER2D: + case GSK_SL_TOKEN_SAMPLER3D: + case GSK_SL_TOKEN_SAMPLERCUBE: + case GSK_SL_TOKEN_SAMPLER1DSHADOW: + case GSK_SL_TOKEN_SAMPLER2DSHADOW: + case GSK_SL_TOKEN_SAMPLERCUBESHADOW: + case GSK_SL_TOKEN_SAMPLER1DARRAY: + case GSK_SL_TOKEN_SAMPLER2DARRAY: + case GSK_SL_TOKEN_SAMPLER1DARRAYSHADOW: + case GSK_SL_TOKEN_SAMPLER2DARRAYSHADOW: + case GSK_SL_TOKEN_ISAMPLER1D: + case GSK_SL_TOKEN_ISAMPLER2D: + case GSK_SL_TOKEN_ISAMPLER3D: + case GSK_SL_TOKEN_ISAMPLERCUBE: + case GSK_SL_TOKEN_ISAMPLER1DARRAY: + case GSK_SL_TOKEN_ISAMPLER2DARRAY: + case GSK_SL_TOKEN_USAMPLER1D: + case GSK_SL_TOKEN_USAMPLER2D: + case GSK_SL_TOKEN_USAMPLER3D: + case GSK_SL_TOKEN_USAMPLERCUBE: + case GSK_SL_TOKEN_USAMPLER1DARRAY: + case GSK_SL_TOKEN_USAMPLER2DARRAY: + case GSK_SL_TOKEN_SAMPLER2DRECT: + case GSK_SL_TOKEN_SAMPLER2DRECTSHADOW: + case GSK_SL_TOKEN_ISAMPLER2DRECT: + case GSK_SL_TOKEN_USAMPLER2DRECT: + case GSK_SL_TOKEN_SAMPLERBUFFER: + case GSK_SL_TOKEN_ISAMPLERBUFFER: + case GSK_SL_TOKEN_USAMPLERBUFFER: + case GSK_SL_TOKEN_SAMPLERCUBEARRAY: + case GSK_SL_TOKEN_SAMPLERCUBEARRAYSHADOW: + case GSK_SL_TOKEN_ISAMPLERCUBEARRAY: + case GSK_SL_TOKEN_USAMPLERCUBEARRAY: + case GSK_SL_TOKEN_SAMPLER2DMS: + case GSK_SL_TOKEN_ISAMPLER2DMS: + case GSK_SL_TOKEN_USAMPLER2DMS: + case GSK_SL_TOKEN_SAMPLER2DMSARRAY: + case GSK_SL_TOKEN_ISAMPLER2DMSARRAY: + case GSK_SL_TOKEN_USAMPLER2DMSARRAY: case GSK_SL_TOKEN_STRUCT: { GskSlType *type; diff --git a/gsk/gsksltype.c b/gsk/gsksltype.c index 4afd840f0e..d16b9599ca 100644 --- a/gsk/gsksltype.c +++ b/gsk/gsksltype.c @@ -21,6 +21,7 @@ #include "gsksltypeprivate.h" #include "gskslfunctionprivate.h" +#include "gskslimagetypeprivate.h" #include "gskslpreprocessorprivate.h" #include "gskslprinterprivate.h" #include "gskslscopeprivate.h" @@ -52,6 +53,7 @@ struct _GskSlTypeClass { void (* free) (GskSlType *type); const char * (* get_name) (const GskSlType *type); GskSlScalarType (* get_scalar_type) (const GskSlType *type); + const GskSlImageType *(* get_image_type) (const GskSlType *type); GskSlType * (* get_index_type) (const GskSlType *type); gsize (* get_index_stride) (const GskSlType *type); guint (* get_length) (const GskSlType *type); @@ -360,6 +362,12 @@ gsk_sl_type_void_get_scalar_type (const GskSlType *type) return GSK_SL_VOID; } +static const GskSlImageType * +gsk_sl_type_void_get_image_type (const GskSlType *type) +{ + return NULL; +} + static GskSlType * gsk_sl_type_void_get_index_type (const GskSlType *type) { @@ -447,6 +455,7 @@ static const GskSlTypeClass GSK_SL_TYPE_VOID = { gsk_sl_type_void_free, gsk_sl_type_void_get_name, gsk_sl_type_void_get_scalar_type, + gsk_sl_type_void_get_image_type, gsk_sl_type_void_get_index_type, gsk_sl_type_void_get_index_stride, gsk_sl_type_void_get_length, @@ -493,6 +502,12 @@ gsk_sl_type_scalar_get_scalar_type (const GskSlType *type) return scalar->scalar; } +static const GskSlImageType * +gsk_sl_type_scalar_get_image_type (const GskSlType *type) +{ + return NULL; +} + static GskSlType * gsk_sl_type_scalar_get_index_type (const GskSlType *type) { @@ -615,6 +630,7 @@ static const GskSlTypeClass GSK_SL_TYPE_SCALAR = { gsk_sl_type_scalar_free, gsk_sl_type_scalar_get_name, gsk_sl_type_scalar_get_scalar_type, + gsk_sl_type_scalar_get_image_type, gsk_sl_type_scalar_get_index_type, gsk_sl_type_scalar_get_index_stride, gsk_sl_type_scalar_get_length, @@ -663,6 +679,12 @@ gsk_sl_type_vector_get_scalar_type (const GskSlType *type) return vector->scalar; } +static const GskSlImageType * +gsk_sl_type_vector_get_image_type (const GskSlType *type) +{ + return NULL; +} + static GskSlType * gsk_sl_type_vector_get_index_type (const GskSlType *type) { @@ -823,6 +845,7 @@ static const GskSlTypeClass GSK_SL_TYPE_VECTOR = { gsk_sl_type_vector_free, gsk_sl_type_vector_get_name, gsk_sl_type_vector_get_scalar_type, + gsk_sl_type_vector_get_image_type, gsk_sl_type_vector_get_index_type, gsk_sl_type_vector_get_index_stride, gsk_sl_type_vector_get_length, @@ -872,6 +895,12 @@ gsk_sl_type_matrix_get_scalar_type (const GskSlType *type) return matrix->scalar; } +static const GskSlImageType * +gsk_sl_type_matrix_get_image_type (const GskSlType *type) +{ + return NULL; +} + static GskSlType * gsk_sl_type_matrix_get_index_type (const GskSlType *type) { @@ -1033,6 +1062,7 @@ static const GskSlTypeClass GSK_SL_TYPE_MATRIX = { gsk_sl_type_matrix_free, gsk_sl_type_matrix_get_name, gsk_sl_type_matrix_get_scalar_type, + gsk_sl_type_matrix_get_image_type, gsk_sl_type_matrix_get_index_type, gsk_sl_type_matrix_get_index_stride, gsk_sl_type_matrix_get_length, @@ -1047,6 +1077,153 @@ static const GskSlTypeClass GSK_SL_TYPE_MATRIX = { gsk_sl_type_matrix_write_value_spv }; +/* SAMPLER */ + +typedef struct _GskSlTypeSampler GskSlTypeSampler; + +struct _GskSlTypeSampler { + GskSlType parent; + + const char *name; + GskSlSamplerType sampler; + + GskSlImageType image_type; +}; + +static void +gsk_sl_type_sampler_free (GskSlType *type) +{ + g_assert_not_reached (); +} + +static const char * +gsk_sl_type_sampler_get_name (const GskSlType *type) +{ + const GskSlTypeSampler *sampler = (const GskSlTypeSampler *) type; + + return sampler->name; +} + +static GskSlScalarType +gsk_sl_type_sampler_get_scalar_type (const GskSlType *type) +{ + return GSK_SL_VOID; +} + +static const GskSlImageType * +gsk_sl_type_sampler_get_image_type (const GskSlType *type) +{ + const GskSlTypeSampler *sampler = (const GskSlTypeSampler *) type; + + return &sampler->image_type; +} + +static GskSlType * +gsk_sl_type_sampler_get_index_type (const GskSlType *type) +{ + return NULL; +} + +static gsize +gsk_sl_type_sampler_get_index_stride (const GskSlType *type) +{ + return 0; +} + +static guint +gsk_sl_type_sampler_get_length (const GskSlType *type) +{ + return 0; +} + +static gsize +gsk_sl_type_sampler_get_size (const GskSlType *type) +{ + /* XXX: setting this to 0 would make it not work in GskSlValue */ + return sizeof (gpointer); +} + +static gsize +gsk_sl_type_sampler_get_n_components (const GskSlType *type) +{ + return 1; +} + +static guint +gsk_sl_type_sampler_get_n_members (const GskSlType *type) +{ + return 0; +} + +static const GskSlTypeMember * +gsk_sl_type_sampler_get_member (const GskSlType *type, + guint n) +{ + return NULL; +} + +static gboolean +gsk_sl_type_sampler_can_convert (const GskSlType *target, + const GskSlType *source) +{ + return gsk_sl_type_equal (target, source); +} + +static guint32 +gsk_sl_type_sampler_write_spv (GskSlType *type, + GskSpvWriter *writer) +{ + GskSlTypeSampler *sampler = (GskSlTypeSampler *) type; + guint32 image_id; + + image_id = gsk_spv_writer_get_id_for_image_type (writer, &sampler->image_type); + + return gsk_spv_writer_type_sampled_image (writer, image_id); +} + +static void +gsk_sl_type_sampler_print_value (const GskSlType *type, + GskSlPrinter *printer, + gconstpointer value) +{ + g_assert_not_reached (); +} + +static gboolean +gsk_sl_type_sampler_value_equal (const GskSlType *type, + gconstpointer a, + gconstpointer b) +{ + return *(gconstpointer *) a == *(gconstpointer *) b; +} + +static guint32 +gsk_sl_type_sampler_write_value_spv (GskSlType *type, + GskSpvWriter *writer, + gconstpointer value) +{ + g_assert_not_reached (); +} + +static const GskSlTypeClass GSK_SL_TYPE_SAMPLER = { + gsk_sl_type_sampler_free, + gsk_sl_type_sampler_get_name, + gsk_sl_type_sampler_get_scalar_type, + gsk_sl_type_sampler_get_image_type, + gsk_sl_type_sampler_get_index_type, + gsk_sl_type_sampler_get_index_stride, + gsk_sl_type_sampler_get_length, + gsk_sl_type_sampler_get_size, + gsk_sl_type_sampler_get_n_components, + gsk_sl_type_sampler_get_n_members, + gsk_sl_type_sampler_get_member, + gsk_sl_type_sampler_can_convert, + gsk_sl_type_sampler_write_spv, + gsk_sl_type_sampler_print_value, + gsk_sl_type_sampler_value_equal, + gsk_sl_type_sampler_write_value_spv +}; + /* STRUCT */ typedef struct _GskSlTypeStruct GskSlTypeStruct; @@ -1093,6 +1270,12 @@ gsk_sl_type_struct_get_scalar_type (const GskSlType *type) return GSK_SL_VOID; } +static const GskSlImageType * +gsk_sl_type_struct_get_image_type (const GskSlType *type) +{ + return NULL; +} + static GskSlType * gsk_sl_type_struct_get_index_type (const GskSlType *type) { @@ -1288,6 +1471,7 @@ static const GskSlTypeClass GSK_SL_TYPE_STRUCT = { gsk_sl_type_struct_free, gsk_sl_type_struct_get_name, gsk_sl_type_struct_get_scalar_type, + gsk_sl_type_struct_get_image_type, gsk_sl_type_struct_get_index_type, gsk_sl_type_struct_get_index_stride, gsk_sl_type_struct_get_length, @@ -1348,6 +1532,12 @@ gsk_sl_type_block_get_scalar_type (const GskSlType *type) return GSK_SL_VOID; } +static const GskSlImageType * +gsk_sl_type_block_get_image_type (const GskSlType *type) +{ + return NULL; +} + static GskSlType * gsk_sl_type_block_get_index_type (const GskSlType *type) { @@ -1507,6 +1697,7 @@ static const GskSlTypeClass GSK_SL_TYPE_BLOCK = { gsk_sl_type_block_free, gsk_sl_type_block_get_name, gsk_sl_type_block_get_scalar_type, + gsk_sl_type_block_get_image_type, gsk_sl_type_block_get_index_type, gsk_sl_type_block_get_index_stride, gsk_sl_type_block_get_length, @@ -1859,6 +2050,126 @@ gsk_sl_type_new_parse (GskSlScope *scope, case GSK_SL_TOKEN_DMAT4X4: type = gsk_sl_type_ref (gsk_sl_type_get_matrix (GSK_SL_DOUBLE, 4, 4)); break; + case GSK_SL_TOKEN_SAMPLER1D: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_1D)); + break; + case GSK_SL_TOKEN_SAMPLER2D: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2D)); + break; + case GSK_SL_TOKEN_SAMPLER3D: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_3D)); + break; + case GSK_SL_TOKEN_SAMPLERCUBE: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_CUBE)); + break; + case GSK_SL_TOKEN_SAMPLER1DSHADOW: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_1D_SHADOW)); + break; + case GSK_SL_TOKEN_SAMPLER2DSHADOW: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2D_SHADOW)); + break; + case GSK_SL_TOKEN_SAMPLERCUBESHADOW: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_CUBE_SHADOW)); + break; + case GSK_SL_TOKEN_SAMPLER1DARRAY: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_1D_ARRAY)); + break; + case GSK_SL_TOKEN_SAMPLER2DARRAY: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2D_ARRAY)); + break; + case GSK_SL_TOKEN_SAMPLER1DARRAYSHADOW: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_1D_ARRAY_SHADOW)); + break; + case GSK_SL_TOKEN_SAMPLER2DARRAYSHADOW: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2D_ARRAY_SHADOW)); + break; + case GSK_SL_TOKEN_ISAMPLER1D: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_1D_INT)); + break; + case GSK_SL_TOKEN_ISAMPLER2D: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2D_INT)); + break; + case GSK_SL_TOKEN_ISAMPLER3D: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_3D_INT)); + break; + case GSK_SL_TOKEN_ISAMPLERCUBE: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_CUBE_INT)); + break; + case GSK_SL_TOKEN_ISAMPLER1DARRAY: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_1D_ARRAY_INT)); + break; + case GSK_SL_TOKEN_ISAMPLER2DARRAY: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2D_ARRAY_INT)); + break; + case GSK_SL_TOKEN_USAMPLER1D: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_1D_UINT)); + break; + case GSK_SL_TOKEN_USAMPLER2D: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2D_UINT)); + break; + case GSK_SL_TOKEN_USAMPLER3D: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_3D_UINT)); + break; + case GSK_SL_TOKEN_USAMPLERCUBE: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_CUBE_UINT)); + break; + case GSK_SL_TOKEN_USAMPLER1DARRAY: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_1D_ARRAY_UINT)); + break; + case GSK_SL_TOKEN_USAMPLER2DARRAY: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2D_ARRAY_UINT)); + break; + case GSK_SL_TOKEN_SAMPLER2DRECT: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2D_RECT)); + break; + case GSK_SL_TOKEN_SAMPLER2DRECTSHADOW: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2D_RECT_SHADOW)); + break; + case GSK_SL_TOKEN_ISAMPLER2DRECT: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2D_RECT_INT)); + break; + case GSK_SL_TOKEN_USAMPLER2DRECT: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2D_RECT_UINT)); + break; + case GSK_SL_TOKEN_SAMPLERBUFFER: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_BUFFER)); + break; + case GSK_SL_TOKEN_ISAMPLERBUFFER: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_BUFFER_INT)); + break; + case GSK_SL_TOKEN_USAMPLERBUFFER: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_BUFFER_UINT)); + break; + case GSK_SL_TOKEN_SAMPLERCUBEARRAY: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_CUBE_ARRAY)); + break; + case GSK_SL_TOKEN_SAMPLERCUBEARRAYSHADOW: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_CUBE_ARRAY_SHADOW)); + break; + case GSK_SL_TOKEN_ISAMPLERCUBEARRAY: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_CUBE_ARRAY_INT)); + break; + case GSK_SL_TOKEN_USAMPLERCUBEARRAY: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_CUBE_ARRAY_UINT)); + break; + case GSK_SL_TOKEN_SAMPLER2DMS: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2DMS)); + break; + case GSK_SL_TOKEN_ISAMPLER2DMS: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2DMS_INT)); + break; + case GSK_SL_TOKEN_USAMPLER2DMS: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2DMS_UINT)); + break; + case GSK_SL_TOKEN_SAMPLER2DMSARRAY: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2DMS_ARRAY)); + break; + case GSK_SL_TOKEN_ISAMPLER2DMSARRAY: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2DMS_ARRAY_INT)); + break; + case GSK_SL_TOKEN_USAMPLER2DMSARRAY: + type = gsk_sl_type_ref (gsk_sl_type_get_sampler (GSK_SL_SAMPLER_2DMS_ARRAY_UINT)); + break; case GSK_SL_TOKEN_STRUCT: return gsk_sl_type_parse_struct (scope, preproc); case GSK_SL_TOKEN_IDENTIFIER: @@ -2003,6 +2314,56 @@ gsk_sl_type_get_matrix (GskSlScalarType scalar, return &builtin_matrix_types[columns - 2][rows - 2][scalar == GSK_SL_FLOAT ? 0 : 1].parent; } +static GskSlTypeSampler +builtin_sampler_types[] = { + [GSK_SL_SAMPLER_1D] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "sampler1D", GSK_SL_SAMPLER_1D, { GSK_SL_FLOAT, GSK_SPV_DIM_1_D, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_1D_INT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "isampler1D", GSK_SL_SAMPLER_1D_INT, { GSK_SL_INT, GSK_SPV_DIM_1_D, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_1D_UINT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "usampler1D", GSK_SL_SAMPLER_1D_UINT, { GSK_SL_UINT, GSK_SPV_DIM_1_D, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_1D_SHADOW] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "sampler1DShadow", GSK_SL_SAMPLER_1D_SHADOW, { GSK_SL_FLOAT, GSK_SPV_DIM_1_D, 1, 0, 0, 1 } }, + [GSK_SL_SAMPLER_2D] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "sampler2D", GSK_SL_SAMPLER_2D, { GSK_SL_FLOAT, GSK_SPV_DIM_2_D, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_2D_INT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "isampler2D", GSK_SL_SAMPLER_2D_INT, { GSK_SL_INT, GSK_SPV_DIM_2_D, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_2D_UINT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "usampler2D", GSK_SL_SAMPLER_2D_UINT, { GSK_SL_UINT, GSK_SPV_DIM_2_D, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_2D_SHADOW] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "sampler2DShadow", GSK_SL_SAMPLER_2D_SHADOW, { GSK_SL_FLOAT, GSK_SPV_DIM_2_D, 1, 0, 0, 1 } }, + [GSK_SL_SAMPLER_3D] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "sampler3D", GSK_SL_SAMPLER_3D, { GSK_SL_FLOAT, GSK_SPV_DIM_3_D, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_3D_INT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "isampler3D", GSK_SL_SAMPLER_3D_INT, { GSK_SL_INT, GSK_SPV_DIM_3_D, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_3D_UINT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "usampler3D", GSK_SL_SAMPLER_3D_UINT, { GSK_SL_UINT, GSK_SPV_DIM_3_D, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_CUBE] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "samplerCube", GSK_SL_SAMPLER_CUBE, { GSK_SL_FLOAT, GSK_SPV_DIM_CUBE, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_CUBE_INT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "isamplerCube", GSK_SL_SAMPLER_CUBE_INT, { GSK_SL_INT, GSK_SPV_DIM_CUBE, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_CUBE_UINT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "usamplerCube", GSK_SL_SAMPLER_CUBE_UINT, { GSK_SL_UINT, GSK_SPV_DIM_CUBE, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_CUBE_SHADOW] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "samplerCubeShadow", GSK_SL_SAMPLER_CUBE_SHADOW, { GSK_SL_FLOAT, GSK_SPV_DIM_CUBE, 1, 0, 0, 1 } }, + [GSK_SL_SAMPLER_2D_RECT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "sampler2DRect", GSK_SL_SAMPLER_2D_RECT, { GSK_SL_FLOAT, GSK_SPV_DIM_RECT, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_2D_RECT_INT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "isampler2DRect", GSK_SL_SAMPLER_2D_RECT_INT, { GSK_SL_INT, GSK_SPV_DIM_RECT, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_2D_RECT_UINT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "usampler2DRect", GSK_SL_SAMPLER_2D_RECT_UINT, { GSK_SL_UINT, GSK_SPV_DIM_RECT, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_2D_RECT_SHADOW] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "sampler2DRectShadow", GSK_SL_SAMPLER_2D_RECT_SHADOW, { GSK_SL_FLOAT, GSK_SPV_DIM_RECT, 1, 0, 0, 1 } }, + [GSK_SL_SAMPLER_1D_ARRAY] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "sampler1DArray", GSK_SL_SAMPLER_1D_ARRAY, { GSK_SL_FLOAT, GSK_SPV_DIM_1_D, 0, 1, 0, 1 } }, + [GSK_SL_SAMPLER_1D_ARRAY_INT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "isampler1DArray", GSK_SL_SAMPLER_1D_ARRAY_INT, { GSK_SL_INT, GSK_SPV_DIM_1_D, 0, 1, 0, 1 } }, + [GSK_SL_SAMPLER_1D_ARRAY_UINT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "usampler1DArray", GSK_SL_SAMPLER_1D_ARRAY_UINT, { GSK_SL_UINT, GSK_SPV_DIM_1_D, 0, 1, 0, 1 } }, + [GSK_SL_SAMPLER_1D_ARRAY_SHADOW] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "sampler1DArrayShadow", GSK_SL_SAMPLER_1D_ARRAY_SHADOW, { GSK_SL_FLOAT, GSK_SPV_DIM_1_D, 1, 1, 0, 1 } }, + [GSK_SL_SAMPLER_2D_ARRAY] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "sampler2DArray", GSK_SL_SAMPLER_2D_ARRAY, { GSK_SL_FLOAT, GSK_SPV_DIM_2_D, 0, 1, 0, 1 } }, + [GSK_SL_SAMPLER_2D_ARRAY_INT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "isampler2DArray", GSK_SL_SAMPLER_2D_ARRAY_INT, { GSK_SL_INT, GSK_SPV_DIM_2_D, 0, 1, 0, 1 } }, + [GSK_SL_SAMPLER_2D_ARRAY_UINT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "usampler2DArray", GSK_SL_SAMPLER_2D_ARRAY_UINT, { GSK_SL_UINT, GSK_SPV_DIM_2_D, 0, 1, 0, 1 } }, + [GSK_SL_SAMPLER_2D_ARRAY_SHADOW] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "sampler2DArrayShadow", GSK_SL_SAMPLER_2D_ARRAY_SHADOW, { GSK_SL_FLOAT, GSK_SPV_DIM_2_D, 1, 1, 0, 1 } }, + [GSK_SL_SAMPLER_CUBE_ARRAY] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "samplerCubeArray", GSK_SL_SAMPLER_CUBE_ARRAY, { GSK_SL_FLOAT, GSK_SPV_DIM_CUBE, 0, 1, 0, 1 } }, + [GSK_SL_SAMPLER_CUBE_ARRAY_INT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "isamplerCubeArray", GSK_SL_SAMPLER_CUBE_ARRAY_INT, { GSK_SL_INT, GSK_SPV_DIM_CUBE, 0, 1, 0, 1 } }, + [GSK_SL_SAMPLER_CUBE_ARRAY_UINT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "usamplerCubeArray", GSK_SL_SAMPLER_CUBE_ARRAY_UINT, { GSK_SL_UINT, GSK_SPV_DIM_CUBE, 0, 1, 0, 1 } }, + [GSK_SL_SAMPLER_CUBE_ARRAY_SHADOW] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "samplerCubeArrayShadow", GSK_SL_SAMPLER_CUBE_ARRAY_SHADOW, { GSK_SL_FLOAT, GSK_SPV_DIM_CUBE, 1, 1, 0, 1 } }, + [GSK_SL_SAMPLER_BUFFER] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "samplerBuffer", GSK_SL_SAMPLER_BUFFER, { GSK_SL_FLOAT, GSK_SPV_DIM_BUFFER, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_BUFFER_INT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "isamplerBuffer", GSK_SL_SAMPLER_BUFFER_INT, { GSK_SL_INT, GSK_SPV_DIM_BUFFER, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_BUFFER_UINT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "usamplerBuffer", GSK_SL_SAMPLER_BUFFER_UINT, { GSK_SL_UINT, GSK_SPV_DIM_BUFFER, 0, 0, 0, 1 } }, + [GSK_SL_SAMPLER_2DMS] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "sampler2DMS", GSK_SL_SAMPLER_2DMS, { GSK_SL_FLOAT, GSK_SPV_DIM_2_D, 0, 0, 1, 1 } }, + [GSK_SL_SAMPLER_2DMS_INT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "isampler2DMS", GSK_SL_SAMPLER_2DMS_INT, { GSK_SL_INT, GSK_SPV_DIM_2_D, 0, 0, 1, 1 } }, + [GSK_SL_SAMPLER_2DMS_UINT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "usampler2DMS", GSK_SL_SAMPLER_2DMS_UINT, { GSK_SL_UINT, GSK_SPV_DIM_2_D, 0, 0, 1, 1 } }, + [GSK_SL_SAMPLER_2DMS_ARRAY] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "sampler2DMSArray", GSK_SL_SAMPLER_2DMS_ARRAY, { GSK_SL_FLOAT, GSK_SPV_DIM_2_D, 0, 1, 1, 1 } }, + [GSK_SL_SAMPLER_2DMS_ARRAY_INT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "isampler2DMSArray", GSK_SL_SAMPLER_2DMS_ARRAY_INT, { GSK_SL_INT, GSK_SPV_DIM_2_D, 0, 1, 1, 1 } }, + [GSK_SL_SAMPLER_2DMS_ARRAY_UINT] = { { &GSK_SL_TYPE_SAMPLER, 1 }, "usampler2DMSArray", GSK_SL_SAMPLER_2DMS_ARRAY_UINT, { GSK_SL_UINT, GSK_SPV_DIM_2_D, 0, 1, 1, 1 } } +}; + +GskSlType * +gsk_sl_type_get_sampler (GskSlSamplerType sampler) +{ + return &builtin_sampler_types[sampler].parent; +} + GskSlType * gsk_sl_type_ref (GskSlType *type) { @@ -2077,9 +2438,15 @@ gsk_sl_type_is_block (const GskSlType *type) } gboolean +gsk_sl_type_is_sampler (const GskSlType *type) +{ + return type->class == &GSK_SL_TYPE_SAMPLER; +} + +gboolean gsk_sl_type_is_opaque (const GskSlType *type) { - return FALSE; + return gsk_sl_type_is_sampler (type); } GskSlScalarType @@ -2088,6 +2455,12 @@ gsk_sl_type_get_scalar_type (const GskSlType *type) return type->class->get_scalar_type (type); } +const GskSlImageType * +gsk_sl_type_get_image_type (const GskSlType *type) +{ + return type->class->get_image_type (type); +} + GskSlType * gsk_sl_type_get_index_type (const GskSlType *type) { diff --git a/gsk/gsksltypeprivate.h b/gsk/gsksltypeprivate.h index 567762c31b..0838b9753c 100644 --- a/gsk/gsksltypeprivate.h +++ b/gsk/gsksltypeprivate.h @@ -38,6 +38,7 @@ GskSlType * gsk_sl_type_get_vector (GskSlScalarType GskSlType * gsk_sl_type_get_matrix (GskSlScalarType scalar, guint columns, guint rows); +GskSlType * gsk_sl_type_get_sampler (GskSlSamplerType sampler); GskSlType * gsk_sl_type_get_matching (GskSlType *type, GskSlScalarType scalar); @@ -51,10 +52,12 @@ gboolean gsk_sl_type_is_matrix (const GskSlType gboolean gsk_sl_type_is_basic (const GskSlType *type); gboolean gsk_sl_type_is_struct (const GskSlType *type); gboolean gsk_sl_type_is_block (const GskSlType *type); +gboolean gsk_sl_type_is_sampler (const GskSlType *type); gboolean gsk_sl_type_is_opaque (const GskSlType *type); const char * gsk_sl_type_get_name (const GskSlType *type); GskSlScalarType gsk_sl_type_get_scalar_type (const GskSlType *type); +const GskSlImageType * gsk_sl_type_get_image_type (const GskSlType *type); GskSlType * gsk_sl_type_get_index_type (const GskSlType *type); gsize gsk_sl_type_get_index_stride (const GskSlType *type); guint gsk_sl_type_get_length (const GskSlType *type); diff --git a/gsk/gsksltypesprivate.h b/gsk/gsksltypesprivate.h index b8e84cfc42..6e26228064 100644 --- a/gsk/gsksltypesprivate.h +++ b/gsk/gsksltypesprivate.h @@ -27,6 +27,7 @@ typedef struct _GskSlExpression GskSlExpression; typedef struct _GskSlFunction GskSlFunction; typedef struct _GskSlFunctionMatcher GskSlFunctionMatcher; typedef struct _GskSlFunctionType GskSlFunctionType; +typedef struct _GskSlImageType GskSlImageType; typedef struct _GskSlNativeFunction GskSlNativeFunction; typedef struct _GskSlPreprocessor GskSlPreprocessor; typedef struct _GskSlPointerType GskSlPointerType; @@ -53,6 +54,50 @@ typedef enum { } GskSlScalarType; typedef enum { + GSK_SL_SAMPLER_1D, + GSK_SL_SAMPLER_1D_INT, + GSK_SL_SAMPLER_1D_UINT, + GSK_SL_SAMPLER_1D_SHADOW, + GSK_SL_SAMPLER_2D, + GSK_SL_SAMPLER_2D_INT, + GSK_SL_SAMPLER_2D_UINT, + GSK_SL_SAMPLER_2D_SHADOW, + GSK_SL_SAMPLER_3D, + GSK_SL_SAMPLER_3D_INT, + GSK_SL_SAMPLER_3D_UINT, + GSK_SL_SAMPLER_CUBE, + GSK_SL_SAMPLER_CUBE_INT, + GSK_SL_SAMPLER_CUBE_UINT, + GSK_SL_SAMPLER_CUBE_SHADOW, + GSK_SL_SAMPLER_2D_RECT, + GSK_SL_SAMPLER_2D_RECT_INT, + GSK_SL_SAMPLER_2D_RECT_UINT, + GSK_SL_SAMPLER_2D_RECT_SHADOW, + GSK_SL_SAMPLER_1D_ARRAY, + GSK_SL_SAMPLER_1D_ARRAY_INT, + GSK_SL_SAMPLER_1D_ARRAY_UINT, + GSK_SL_SAMPLER_1D_ARRAY_SHADOW, + GSK_SL_SAMPLER_2D_ARRAY, + GSK_SL_SAMPLER_2D_ARRAY_INT, + GSK_SL_SAMPLER_2D_ARRAY_UINT, + GSK_SL_SAMPLER_2D_ARRAY_SHADOW, + GSK_SL_SAMPLER_CUBE_ARRAY, + GSK_SL_SAMPLER_CUBE_ARRAY_INT, + GSK_SL_SAMPLER_CUBE_ARRAY_UINT, + GSK_SL_SAMPLER_CUBE_ARRAY_SHADOW, + GSK_SL_SAMPLER_BUFFER, + GSK_SL_SAMPLER_BUFFER_INT, + GSK_SL_SAMPLER_BUFFER_UINT, + GSK_SL_SAMPLER_2DMS, + GSK_SL_SAMPLER_2DMS_INT, + GSK_SL_SAMPLER_2DMS_UINT, + GSK_SL_SAMPLER_2DMS_ARRAY, + GSK_SL_SAMPLER_2DMS_ARRAY_INT, + GSK_SL_SAMPLER_2DMS_ARRAY_UINT, + GSK_SL_N_SAMPLER_TYPES +} GskSlSamplerType; + +typedef enum { GSK_SL_STORAGE_DEFAULT, GSK_SL_STORAGE_GLOBAL, diff --git a/gsk/gskspvwriter.c b/gsk/gskspvwriter.c index 8f7ef8616b..a197d5a018 100644 --- a/gsk/gskspvwriter.c +++ b/gsk/gskspvwriter.c @@ -22,6 +22,7 @@ #include "gskslfunctionprivate.h" #include "gskslfunctiontypeprivate.h" +#include "gskslimagetypeprivate.h" #include "gskslqualifierprivate.h" #include "gsksltypeprivate.h" #include "gskslvalueprivate.h" @@ -58,6 +59,7 @@ struct _GskSpvWriter GSList *pending_blocks; GHashTable *types; + GHashTable *image_types; GHashTable *pointer_types; GHashTable *values; GHashTable *variables; @@ -140,6 +142,8 @@ gsk_spv_writer_new (GskSlShaderStage stage) writer->types = g_hash_table_new_full (gsk_sl_type_hash, gsk_sl_type_equal, (GDestroyNotify) gsk_sl_type_unref, NULL); + writer->image_types = g_hash_table_new_full (gsk_sl_image_type_hash, gsk_sl_image_type_equal, + NULL, NULL); writer->pointer_types = g_hash_table_new_full (pointer_type_hash, pointer_type_equal, pointer_type_free, NULL); writer->values = g_hash_table_new_full (gsk_sl_value_hash, gsk_sl_value_equal, @@ -185,6 +189,7 @@ gsk_spv_writer_unref (GskSpvWriter *writer) g_hash_table_destroy (writer->pointer_types); g_hash_table_destroy (writer->types); + g_hash_table_destroy (writer->image_types); g_hash_table_destroy (writer->values); g_hash_table_destroy (writer->variables); g_hash_table_destroy (writer->functions); @@ -342,6 +347,7 @@ gsk_spv_writer_clear (GskSpvWriter *writer) g_hash_table_remove_all (writer->pointer_types); g_hash_table_remove_all (writer->types); + g_hash_table_remove_all (writer->image_types); g_hash_table_remove_all (writer->values); g_hash_table_remove_all (writer->variables); g_hash_table_remove_all (writer->functions); @@ -412,6 +418,21 @@ gsk_spv_writer_get_id_for_type (GskSpvWriter *writer, } guint32 +gsk_spv_writer_get_id_for_image_type (GskSpvWriter *writer, + const GskSlImageType *type) +{ + guint32 result; + + result = GPOINTER_TO_UINT (g_hash_table_lookup (writer->image_types, type)); + if (result != 0) + return result; + + result = gsk_sl_image_type_write_spv (type, writer); + g_hash_table_insert (writer->image_types, (gpointer) type, GUINT_TO_POINTER (result)); + return result; +} + +guint32 gsk_spv_writer_get_id_for_pointer_type (GskSpvWriter *writer, GskSlType *type, GskSpvStorageClass storage) @@ -446,6 +467,23 @@ gsk_spv_writer_get_id_for_value (GskSpvWriter *writer, return result; } +GskSlValue * +gsk_spv_writer_get_value_for_id (GskSpvWriter *writer, + guint32 id) +{ + GHashTableIter iter; + gpointer value, value_id; + + g_hash_table_iter_init (&iter, writer->values); + while (g_hash_table_iter_next (&iter, &value, &value_id)) + { + if (GPOINTER_TO_UINT (value_id) == id) + return value; + } + + return NULL; +} + guint32 gsk_spv_writer_get_id_for_zero (GskSpvWriter *writer, GskSlType *type) diff --git a/gsk/gskspvwriterprivate.h b/gsk/gskspvwriterprivate.h index 37342b24ff..4d7e1d3ce5 100644 --- a/gsk/gskspvwriterprivate.h +++ b/gsk/gskspvwriterprivate.h @@ -61,11 +61,15 @@ guint32 gsk_spv_writer_get_id_for_extended_instructions (GskSpvWriter *writer); guint32 gsk_spv_writer_get_id_for_type (GskSpvWriter *writer, GskSlType *type); +guint32 gsk_spv_writer_get_id_for_image_type (GskSpvWriter *writer, + const GskSlImageType *type); guint32 gsk_spv_writer_get_id_for_pointer_type (GskSpvWriter *writer, GskSlType *type, GskSpvStorageClass storage); guint32 gsk_spv_writer_get_id_for_value (GskSpvWriter *writer, GskSlValue *value); +GskSlValue * gsk_spv_writer_get_value_for_id (GskSpvWriter *writer, + guint32 id); guint32 gsk_spv_writer_get_id_for_zero (GskSpvWriter *writer, GskSlType *type); guint32 gsk_spv_writer_get_id_for_one (GskSpvWriter *writer, diff --git a/gsk/meson.build b/gsk/meson.build index 5935a35999..6302062d07 100644 --- a/gsk/meson.build +++ b/gsk/meson.build @@ -42,6 +42,7 @@ gsk_private_sources = files([ 'gskslexpression.c', 'gskslfunction.c', 'gskslfunctiontype.c', + 'gskslimagetype.c', 'gskslnativefunction.c', 'gskslpreprocessor.c', 'gskslprinter.c', |