Compare commits

...

3 Commits

Author SHA1 Message Date
Matthias Clasen
84c6a1a8cf Add a shader tool
This tool will do what is necessary to populate the Vulkan shader
cache with most of the shaders that GTK will need.
2024-04-30 18:38:25 -04:00
Matthias Clasen
57f3598b71 gsk: Export some shader api
We need a way to get at the shader op classes, so an external
tool can use them.
2024-04-30 18:38:25 -04:00
Matthias Clasen
422fc3dda4 gdk: Export some pipeline cache api
This will be used in a tool to precompile shaders.
2024-04-30 18:38:25 -04:00
24 changed files with 513 additions and 17 deletions

View File

@@ -1229,6 +1229,18 @@ gdk_display_vulkan_pipeline_cache_updated (GdkDisplay *display)
NULL);
}
gboolean
gdk_display_vulkan_pipeline_cache_save (GdkDisplay *display)
{
return gdk_vulkan_save_pipeline_cache (display);
}
GFile *
gdk_display_vulkan_pipeline_cache_file (GdkDisplay *display)
{
return gdk_vulkan_get_pipeline_cache_file (display);
}
static void
gdk_display_create_pipeline_cache (GdkDisplay *display)
{

View File

@@ -87,6 +87,8 @@ VkShaderModule gdk_display_get_vk_shader_module (GdkDisp
const char *resource_name);
void gdk_display_vulkan_pipeline_cache_updated (GdkDisplay *display);
gboolean gdk_display_vulkan_pipeline_cache_save (GdkDisplay *display);
GFile * gdk_display_vulkan_pipeline_cache_file (GdkDisplay *display);
VkInstance gdk_vulkan_context_get_instance (GdkVulkanContext *context);
VkPhysicalDevice gdk_vulkan_context_get_physical_device (GdkVulkanContext *context);

View File

@@ -29,7 +29,7 @@ gsk_gpu_blend_mode_op_print_instance (GskGpuShaderOp *shader,
gsk_gpu_print_image_descriptor (string, shader->desc, instance->top_id);
}
static const GskGpuShaderOpClass GSK_GPU_BLEND_MODE_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_BLEND_MODE_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuBlendModeOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -31,7 +31,7 @@ gsk_gpu_blur_op_print_instance (GskGpuShaderOp *shader,
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
}
static const GskGpuShaderOpClass GSK_GPU_BLUR_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_BLUR_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuBlurOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -72,7 +72,7 @@ gsk_gpu_border_op_gl_command (GskGpuOp *op,
return gsk_gpu_shader_op_gl_command_n (op, frame, state, 8);
}
static const GskGpuShaderOpClass GSK_GPU_BORDER_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_BORDER_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuBorderOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -51,7 +51,7 @@ gsk_gpu_box_shadow_op_gl_command (GskGpuOp *op,
return gsk_gpu_shader_op_gl_command_n (op, frame, state, 8);
}
static const GskGpuShaderOpClass GSK_GPU_BOX_SHADOW_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_BOX_SHADOW_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuBoxShadowOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -27,7 +27,7 @@ gsk_gpu_colorize_op_print_instance (GskGpuShaderOp *shader,
gsk_gpu_print_rgba (string, instance->color);
}
static const GskGpuShaderOpClass GSK_GPU_COLORIZE_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_COLORIZE_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuColorizeOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -26,7 +26,7 @@ gsk_gpu_color_matrix_op_print_instance (GskGpuShaderOp *shader,
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
}
static const GskGpuShaderOpClass GSK_GPU_COLOR_MATRIX_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_COLOR_MATRIX_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuColorMatrixOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -27,7 +27,7 @@ gsk_gpu_color_op_print_instance (GskGpuShaderOp *shader,
gsk_gpu_print_rgba (string, instance->color);
}
static const GskGpuShaderOpClass GSK_GPU_COLOR_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_COLOR_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuColorOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -27,7 +27,7 @@ gsk_gpu_conic_gradient_op_print_instance (GskGpuShaderOp *shader,
gsk_gpu_print_rect (string, instance->rect);
}
static const GskGpuShaderOpClass GSK_GPU_CONIC_GRADIENT_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_CONIC_GRADIENT_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuConicGradientOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -28,7 +28,7 @@ gsk_gpu_cross_fade_op_print_instance (GskGpuShaderOp *shader,
g_string_append_printf (string, "%g%%", 100 * instance->opacity_progress[1]);
}
static const GskGpuShaderOpClass GSK_GPU_CROSS_FADE_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_CROSS_FADE_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuCrossFadeOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -30,7 +30,7 @@ gsk_gpu_linear_gradient_op_print_instance (GskGpuShaderOp *shader,
gsk_gpu_print_rect (string, instance->rect);
}
static const GskGpuShaderOpClass GSK_GPU_LINEAR_GRADIENT_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_LINEAR_GRADIENT_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuLinearGradientOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -27,7 +27,7 @@ gsk_gpu_mask_op_print_instance (GskGpuShaderOp *shader,
gsk_gpu_print_image_descriptor (string, shader->desc, instance->mask_id);
}
static const GskGpuShaderOpClass GSK_GPU_MASK_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_MASK_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuMaskOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -30,7 +30,7 @@ gsk_gpu_radial_gradient_op_print_instance (GskGpuShaderOp *shader,
gsk_gpu_print_rect (string, instance->rect);
}
static const GskGpuShaderOpClass GSK_GPU_RADIAL_GRADIENT_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_RADIAL_GRADIENT_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuRadialGradientOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -27,7 +27,7 @@ gsk_gpu_rounded_color_op_print_instance (GskGpuShaderOp *shader,
gsk_gpu_print_rgba (string, instance->color);
}
static const GskGpuShaderOpClass GSK_GPU_ROUNDED_COLOR_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_ROUNDED_COLOR_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuRoundedColorOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -268,3 +268,45 @@ gsk_gpu_shader_op_alloc (GskGpuFrame *frame,
*((gpointer *) out_vertex_data) = gsk_gpu_frame_get_vertex_data (frame, vertex_offset);
}
extern const GskGpuShaderOpClass GSK_GPU_BLEND_MODE_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_BLUR_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_BORDER_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_BOX_SHADOW_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_COLORIZE_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_COLOR_MATRIX_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_COLOR_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_CONIC_GRADIENT_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_CROSS_FADE_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_LINEAR_GRADIENT_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_MASK_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_RADIAL_GRADIENT_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_ROUNDED_COLOR_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_STRAIGHT_ALPHA_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_TEXTURE_OP_CLASS;
extern const GskGpuShaderOpClass GSK_GPU_UBER_OP_CLASS;
#define CHECK_CLASS(class) if (strcmp (name, class.shader_name) == 0) return &class
const GskGpuShaderOpClass *
gsk_gpu_shader_op_class_from_name (const char *name)
{
CHECK_CLASS (GSK_GPU_BLEND_MODE_OP_CLASS);
else CHECK_CLASS (GSK_GPU_BLUR_OP_CLASS);
else CHECK_CLASS (GSK_GPU_BORDER_OP_CLASS);
else CHECK_CLASS (GSK_GPU_BOX_SHADOW_OP_CLASS);
else CHECK_CLASS (GSK_GPU_COLORIZE_OP_CLASS);
else CHECK_CLASS (GSK_GPU_COLOR_MATRIX_OP_CLASS);
else CHECK_CLASS (GSK_GPU_COLOR_OP_CLASS);
else CHECK_CLASS (GSK_GPU_CROSS_FADE_OP_CLASS);
else CHECK_CLASS (GSK_GPU_LINEAR_GRADIENT_OP_CLASS);
else CHECK_CLASS (GSK_GPU_MASK_OP_CLASS);
else CHECK_CLASS (GSK_GPU_RADIAL_GRADIENT_OP_CLASS);
else CHECK_CLASS (GSK_GPU_ROUNDED_COLOR_OP_CLASS);
else CHECK_CLASS (GSK_GPU_STRAIGHT_ALPHA_OP_CLASS);
else CHECK_CLASS (GSK_GPU_TEXTURE_OP_CLASS);
else CHECK_CLASS (GSK_GPU_UBER_OP_CLASS);
g_warning ("No such shader op: %s\n", name);
return NULL;
}

View File

@@ -84,5 +84,7 @@ gsk_gpu_point_to_float (const graphene_point_t *point,
values[1] = point->y + offset->y;
}
const GskGpuShaderOpClass * gsk_gpu_shader_op_class_from_name (const char *name);
G_END_DECLS

View File

@@ -29,7 +29,7 @@ gsk_gpu_straight_alpha_op_print_instance (GskGpuShaderOp *shader,
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
}
static const GskGpuShaderOpClass GSK_GPU_STRAIGHT_ALPHA_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_STRAIGHT_ALPHA_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuStraightAlphaOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -26,7 +26,7 @@ gsk_gpu_texture_op_print_instance (GskGpuShaderOp *shader,
gsk_gpu_print_image_descriptor (string, shader->desc, instance->tex_id);
}
static const GskGpuShaderOpClass GSK_GPU_TEXTURE_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_TEXTURE_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuTextureOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -26,7 +26,7 @@ gsk_gpu_uber_op_print_instance (GskGpuShaderOp *shader,
gsk_gpu_print_rect (string, instance->rect);
}
static const GskGpuShaderOpClass GSK_GPU_UBER_OP_CLASS = {
const GskGpuShaderOpClass GSK_GPU_UBER_OP_CLASS = {
{
GSK_GPU_OP_SIZE (GskGpuUberOp),
GSK_GPU_STAGE_SHADER,

View File

@@ -0,0 +1,315 @@
/* Copyright 2024 Red Hat, Inc.
*
* GTK+ 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.
*
* GLib 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 GTK+; see the file COPYING. If not,
* see <http://www.gnu.org/licenses/>.
*
* Author: Matthias Clasen
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <glib/gi18n-lib.h>
#include <glib/gprintf.h>
#include <glib/gstdio.h>
#include <gtk/gtk.h>
#include "gdk/gdkvulkancontextprivate.h"
#include "gsk/gpu/gskgputypesprivate.h"
#include "gsk/gpu/gskvulkandeviceprivate.h"
#include "gsk/gpu/gskgpushaderopprivate.h"
#include "gtk-shader-tool.h"
static gboolean verbose;
typedef struct {
const GskGpuShaderOpClass *op_class;
unsigned int variation;
GskGpuShaderClip clip;
GskGpuBlend blend;
VkFormat format;
gsize n_buffers;
gsize n_samplers;
gsize n_immutable_samplers;
} PipelineData;
static const char *clip_name[] = { "NONE", "RECT", "ROUNDED" };
static const char *blend_name[] = { "OVER", "ADD", "CLEAR" };
static gboolean
parse_line (const char *line,
PipelineData *data)
{
char *p, *q;
char *name;
char *parms;
char **split;
int i;
if (!g_str_has_prefix (line, "Create Vulkan pipeline ("))
return FALSE;
line += strlen ("Create Vulkan pipeline (");
p = strchr (line, ' ');
if (!p)
return FALSE;
name = g_strndup (line, p - line);
data->op_class = gsk_gpu_shader_op_class_from_name (name);
if (!data->op_class)
{
g_printerr ("%s\n", g_strdup_printf (_("No such shader: %s"), name));
return FALSE;
}
g_free (name);
p++;
p = strchr (p, ' ');
if (!p)
return FALSE;
q = strstr (p, ") for layout (");
if (!q)
return FALSE;
parms = g_strndup (p, q - p);
split = g_strsplit (parms, "/", 0);
g_free (parms);
if (g_strv_length (split) != 4)
{
g_strfreev (split);
return FALSE;
}
data->variation = (unsigned int) g_ascii_strtoull (split[0], NULL, 10);
for (i = 0; i < G_N_ELEMENTS (clip_name); i++)
{
if (strcmp (split[1], clip_name[i]) == 0)
{
data->clip = i;
break;
}
}
if (i == G_N_ELEMENTS (clip_name))
{
g_printerr ("%s\n", g_strdup_printf (_("No such clip: %s"), split[1]));
g_strfreev (split);
return FALSE;
}
for (i = 0; i < G_N_ELEMENTS (blend_name); i++)
{
if (strcmp (split[2], blend_name[i]) == 0)
{
data->blend = i;
break;
}
}
if (i == G_N_ELEMENTS (blend_name))
{
g_printerr ("%s\n", g_strdup_printf (_("No such blend: %s"), split[2]));
g_strfreev (split);
return FALSE;
}
data->format = (guint) g_ascii_strtoull (split[3], NULL, 10);
g_strfreev (split);
p = q + strlen (") for layout (");
q = strstr (p, ")");
if (!q)
return FALSE;
parms = g_strndup (p, q - p);
split = g_strsplit (parms, "/", 0);
g_free (parms);
if (g_strv_length (split ) != 3)
{
g_strfreev (split);
return FALSE;
}
data->n_buffers = (gsize) g_ascii_strtoull (split[0], NULL, 10);
data->n_samplers = (gsize) g_ascii_strtoull (split[1], NULL, 10);
data->n_immutable_samplers = (gsize) g_ascii_strtoull (split[2], NULL, 10);
g_strfreev (split);
return TRUE;
}
static gboolean
compile_shader (GskVulkanDevice *device,
PipelineData *data)
{
GskVulkanPipelineLayout *layout;
VkRenderPass render_pass;
VkPipeline pipeline;
if (data->n_immutable_samplers != 0)
{
g_printerr ("%s\n", _("Can't handle pipeline layouts with immutable samplers\n"));
return FALSE;
}
if (verbose)
{
g_print ("layout: %3lu buffers %3lu samplers ",
data->n_buffers, data->n_samplers);
g_print ("shader: %20s, variation %u clip %7s blend %5s format %u\n",
data->op_class->shader_name,
data->variation,
clip_name[data->clip],
blend_name[data->blend],
data->format);
}
layout = gsk_vulkan_device_acquire_pipeline_layout (device,
NULL,
data->n_immutable_samplers,
data->n_samplers,
data->n_buffers);
render_pass = gsk_vulkan_device_get_vk_render_pass (device,
data->format,
VK_IMAGE_LAYOUT_PREINITIALIZED,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
pipeline = gsk_vulkan_device_get_vk_pipeline (device,
layout,
data->op_class,
data->variation,
data->clip,
data->blend,
data->format,
render_pass);
gsk_vulkan_device_release_pipeline_layout (device, layout);
return pipeline != VK_NULL_HANDLE;
}
static void
compile_shaders_from_file (GskVulkanDevice *device,
const char *filename)
{
char *buffer;
gsize size;
GError *error = NULL;
char **lines;
PipelineData data;
if (!g_file_get_contents (filename, &buffer, &size, &error))
{
char *msg = g_strdup_printf (_("Failed to read %s"), filename);
g_printerr ("%s: %s\n", msg, error->message);
exit (1);
}
lines = g_strsplit (buffer, "\n", 0);
for (int i = 0; lines[i]; i++)
{
lines[i] = g_strstrip (lines[i]);
if (strlen (lines[i]) == 0)
continue;
if (!parse_line (lines[i], &data))
{
char *msg = g_strdup_printf (_("Could not parse line %d: %s"), i + 1, lines[i]);
g_printerr ("%s\n", msg);
exit (1);
}
if (!compile_shader (device, &data))
{
char *msg = g_strdup_printf (_("Failed to compile shader for line %d: %s"), i + 1, lines[i]);
g_printerr ("%s\n", msg);
exit (1);
}
}
g_strfreev (lines);
g_free (buffer);
}
void
do_compile (int *argc,
const char ***argv)
{
GError *error = NULL;
char **args = NULL;
GOptionContext *context;
const GOptionEntry entries[] = {
{ "verbose", 0, 0, G_OPTION_ARG_NONE, &verbose, N_("Be verbose"), NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, NULL, N_("FILE") },
{ NULL, }
};
GdkDisplay *display;
GskGpuDevice *device;
g_set_prgname ("gtk4-shader-tool compile");
context = g_option_context_new (NULL);
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_set_summary (context, _("Compile shaders."));
if (!g_option_context_parse (context, argc, (char ***)argv, &error))
{
g_printerr ("%s\n", error->message);
g_error_free (error);
exit (1);
}
g_option_context_free (context);
if (args == NULL)
{
g_printerr ("%s\n", _("No file specified."));
exit (1);
}
display = gdk_display_get_default ();
device = gsk_vulkan_device_get_for_display (display, &error);
if (device == NULL)
{
g_printerr ("%s: %s\n", _("Failed to get Vulkan device"), error->message);
exit (1);
}
for (int i = 0; args[i]; i++)
compile_shaders_from_file (GSK_VULKAN_DEVICE (device), args[i]);
if (gdk_display_vulkan_pipeline_cache_save (display))
{
GFile *file = gdk_display_vulkan_pipeline_cache_file (display);
g_print (_("Pipeline cache in %s\n"), g_file_peek_path (file));
g_object_unref (file);
}
g_strfreev (args);
}

113
tools/gtk-shader-tool.c Normal file
View File

@@ -0,0 +1,113 @@
/* Copyright 2023 Red Hat, Inc.
*
* GTK 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.
*
* GTK 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 GTK; see the file COPYING. If not,
* see <http://www.gnu.org/licenses/>.
*
* Author: Matthias Clasen
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <glib/gi18n-lib.h>
#include <glib/gprintf.h>
#include <glib/gstdio.h>
#include <gtk/gtk.h>
#include "gtk-shader-tool.h"
static void G_GNUC_NORETURN
usage (void)
{
g_print (_("Usage:\n"
" gtk4-shader-tool [COMMAND] [OPTION…] FILE\n"
"\n"
"Perform various tasks on GTK shaders.\n"
"\n"
"Commands:\n"
" compile Compile Vulkan pipelines\n"
"\n"));
exit (1);
}
static GLogWriterOutput
log_writer_func (GLogLevelFlags level,
const GLogField *fields,
gsize n_fields,
gpointer user_data)
{
gsize i;
const char *domain = NULL;
const char *message = NULL;
for (i = 0; i < n_fields; i++)
{
if (g_strcmp0 (fields[i].key, "GLIB_DOMAIN") == 0)
domain = fields[i].value;
else if (g_strcmp0 (fields[i].key, "MESSAGE") == 0)
message = fields[i].value;
}
if (message != NULL && !g_log_writer_default_would_drop (level, domain))
{
const char *prefix;
switch (level & G_LOG_LEVEL_MASK)
{
case G_LOG_LEVEL_ERROR:
prefix = "ERROR";
break;
case G_LOG_LEVEL_CRITICAL:
prefix = "CRITICAL";
break;
case G_LOG_LEVEL_WARNING:
prefix = "WARNING";
break;
default:
prefix = "INFO";
break;
}
g_printerr ("%s-%s: %s\n", domain, prefix, message);
}
return G_LOG_WRITER_HANDLED;
}
int
main (int argc, const char *argv[])
{
g_set_prgname ("gtk-shader-tool");
g_log_set_writer_func (log_writer_func, NULL, NULL);
gtk_init ();
if (argc < 2)
usage ();
if (strcmp (argv[1], "--help") == 0)
usage ();
argv++;
argc--;
if (strcmp (argv[0], "compile") == 0)
do_compile (&argc, &argv);
else
usage ();
return 0;
}

3
tools/gtk-shader-tool.h Normal file
View File

@@ -0,0 +1,3 @@
#pragma once
void do_compile (int *argc, const char ***argv);

View File

@@ -52,6 +52,13 @@ gtk_tools = [
['gtk4-encode-symbolic-svg', ['encodesymbolic.c'], [ libgtk_static_dep ] ],
]
if vulkan_dep.found()
gtk_tools += [[ 'gtk4-shader-tool',
[ 'gtk-shader-tool.c',
'gtk-shader-tool-compile.c' ],
[ libgtk_static_dep ]]]
endif
if os_unix
gtk_tools += [['gtk4-launch', ['gtk-launch.c'], [libgtk_dep]]]
endif
@@ -64,7 +71,7 @@ foreach tool: gtk_tools
exe = executable(tool_name,
sources: tool_srcs,
include_directories: [confinc],
c_args: common_cflags + [ '-DBUILD_TOOLS' ],
c_args: common_cflags + [ '-DBUILD_TOOLS', '-I../gsk' ],
dependencies: tool_deps,
install: true,
)