mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-04-13 05:43:18 -07:00
vkd3d-shader/spirv: Implement outputting opcode names.
This commit is contained in:
parent
997f3f8266
commit
bebc550f02
Notes:
Henri Verbeet
2025-03-10 15:22:45 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1382
14
Makefile.am
14
Makefile.am
@ -2,6 +2,7 @@ ACLOCAL_AMFLAGS = -I m4
|
|||||||
AM_CFLAGS = @VKD3D_CFLAGS@
|
AM_CFLAGS = @VKD3D_CFLAGS@
|
||||||
AM_CPPFLAGS = -I$(srcdir)/include -I$(srcdir)/include/private -I$(builddir)/include/private
|
AM_CPPFLAGS = -I$(srcdir)/include -I$(srcdir)/include/private -I$(builddir)/include/private
|
||||||
AM_LDFLAGS = -no-undefined
|
AM_LDFLAGS = -no-undefined
|
||||||
|
VKD3D_PERL = $(PERL) -w
|
||||||
|
|
||||||
widl_headers = \
|
widl_headers = \
|
||||||
include/vkd3d_d3d12.h \
|
include/vkd3d_d3d12.h \
|
||||||
@ -319,6 +320,7 @@ vkd3d_demos_headers = \
|
|||||||
demos/demo_xcb.h
|
demos/demo_xcb.h
|
||||||
|
|
||||||
BUILT_SOURCES = $(widl_headers) \
|
BUILT_SOURCES = $(widl_headers) \
|
||||||
|
include/private/spirv_grammar.h \
|
||||||
include/private/vkd3d_version.h
|
include/private/vkd3d_version.h
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libvkd3d-common.la
|
noinst_LTLIBRARIES = libvkd3d-common.la
|
||||||
@ -377,6 +379,7 @@ nodist_libvkd3d_shader_la_SOURCES = $(vkd3d_shader_yyfiles)
|
|||||||
libvkd3d_shader_la_SOURCES = \
|
libvkd3d_shader_la_SOURCES = \
|
||||||
include/private/list.h \
|
include/private/list.h \
|
||||||
include/private/rbtree.h \
|
include/private/rbtree.h \
|
||||||
|
include/private/spirv_grammar.h \
|
||||||
include/private/vkd3d_common.h \
|
include/private/vkd3d_common.h \
|
||||||
include/private/vkd3d_memory.h \
|
include/private/vkd3d_memory.h \
|
||||||
include/vkd3d_shader.h \
|
include/vkd3d_shader.h \
|
||||||
@ -578,6 +581,15 @@ libvkd3d.pc: $(srcdir)/libs/vkd3d/libvkd3d.pc.in Makefile
|
|||||||
-e 's![@]PACKAGE_VERSION[@]!$(PACKAGE_VERSION)!g' \
|
-e 's![@]PACKAGE_VERSION[@]!$(PACKAGE_VERSION)!g' \
|
||||||
$< > $@
|
$< > $@
|
||||||
|
|
||||||
|
VKD3D_V_PERL = $(vkd3d_v_perl_@AM_V@)
|
||||||
|
vkd3d_v_perl_ = $(vkd3d_v_perl_@AM_DEFAULT_V@)
|
||||||
|
vkd3d_v_perl_0 = @echo " PERL " $@;
|
||||||
|
vkd3d_v_perl_1 =
|
||||||
|
|
||||||
|
include/private/spirv_grammar.h: libs/vkd3d-shader/make_spirv include/private/spirv.core.grammar.json
|
||||||
|
@$(MKDIR_P) $(@D)
|
||||||
|
$(VKD3D_V_PERL)$(VKD3D_PERL) $^ > $@.tmp && mv $@.tmp $@
|
||||||
|
|
||||||
include/private/vkd3d_version.h: dummy-vkd3d-version
|
include/private/vkd3d_version.h: dummy-vkd3d-version
|
||||||
@$(MKDIR_P) include/private
|
@$(MKDIR_P) include/private
|
||||||
version=`(GIT_DIR=$(top_srcdir)/.git git rev-parse --short HEAD 2>/dev/null || echo '') \
|
version=`(GIT_DIR=$(top_srcdir)/.git git rev-parse --short HEAD 2>/dev/null || echo '') \
|
||||||
@ -586,7 +598,7 @@ include/private/vkd3d_version.h: dummy-vkd3d-version
|
|||||||
&& (echo $$version | cmp -s - $@) \
|
&& (echo $$version | cmp -s - $@) \
|
||||||
|| echo $$version >$@ || ($(RM) $@ && exit 1)
|
|| echo $$version >$@ || ($(RM) $@ && exit 1)
|
||||||
.SILENT: include/private/vkd3d_version.h
|
.SILENT: include/private/vkd3d_version.h
|
||||||
CLEANFILES += include/private/vkd3d_version.h
|
CLEANFILES += include/private/spirv_grammar.h include/private/vkd3d_version.h
|
||||||
|
|
||||||
.PHONY: dummy-vkd3d-version
|
.PHONY: dummy-vkd3d-version
|
||||||
dummy-vkd3d-version:
|
dummy-vkd3d-version:
|
||||||
|
3
README
3
README
@ -9,7 +9,8 @@ similar, but not identical, to Direct3D 12.
|
|||||||
Building vkd3d
|
Building vkd3d
|
||||||
==============
|
==============
|
||||||
|
|
||||||
Vkd3d depends on SPIRV-Headers and Vulkan-Headers (>= 1.3.228).
|
Vkd3d depends on SPIRV-Headers and Vulkan-Headers (>= 1.3.228), as well as Perl
|
||||||
|
and libjson-perl.
|
||||||
|
|
||||||
Vkd3d generates some of its headers from IDL files. If you are using the
|
Vkd3d generates some of its headers from IDL files. If you are using the
|
||||||
release tarballs, then these headers are pre-generated and are included. If
|
release tarballs, then these headers are pre-generated and are included. If
|
||||||
|
@ -5,6 +5,7 @@ AC_CONFIG_AUX_DIR([bin])
|
|||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
AC_CONFIG_HEADERS(include/config.h)
|
AC_CONFIG_HEADERS(include/config.h)
|
||||||
|
|
||||||
|
AC_ARG_VAR([PERL], [The Perl 5 language interpreter])
|
||||||
AC_ARG_VAR([WIDL], [widl IDL compiler])
|
AC_ARG_VAR([WIDL], [widl IDL compiler])
|
||||||
AC_ARG_VAR([CROSSCC32], [32-bit Windows cross compiler])
|
AC_ARG_VAR([CROSSCC32], [32-bit Windows cross compiler])
|
||||||
AC_ARG_VAR([CROSSCC64], [64-bit Windows cross compiler])
|
AC_ARG_VAR([CROSSCC64], [64-bit Windows cross compiler])
|
||||||
@ -32,6 +33,11 @@ AC_PROG_MKDIR_P
|
|||||||
VKD3D_PROG_WIDL(3, 21)
|
VKD3D_PROG_WIDL(3, 21)
|
||||||
AS_IF([test "x$WIDL" = "xno"], [AC_MSG_WARN([widl is required to build header files.])])
|
AS_IF([test "x$WIDL" = "xno"], [AC_MSG_WARN([widl is required to build header files.])])
|
||||||
|
|
||||||
|
AC_CHECK_PROGS([PERL], [perl], [none])
|
||||||
|
AS_IF([test "$PERL" = "none"], [AC_MSG_ERROR([no suitable perl found. Please install the 'perl-base' package.])])
|
||||||
|
VKD3D_CHECK_PERL_MODULE([JSON],
|
||||||
|
[AC_MSG_ERROR([perl module 'JSON' not found. Please install the 'libjson-perl' package.])])
|
||||||
|
|
||||||
AC_CHECK_PROGS([FLEX], [flex], [none])
|
AC_CHECK_PROGS([FLEX], [flex], [none])
|
||||||
AS_IF([test "$FLEX" = "none"], [AC_MSG_ERROR([no suitable flex found. Please install the 'flex' package.])])
|
AS_IF([test "$FLEX" = "none"], [AC_MSG_ERROR([no suitable flex found. Please install the 'flex' package.])])
|
||||||
AC_ARG_VAR([LFLAGS], [extra flags for flex])
|
AC_ARG_VAR([LFLAGS], [extra flags for flex])
|
||||||
|
17027
include/private/spirv.core.grammar.json
Normal file
17027
include/private/spirv.core.grammar.json
Normal file
File diff suppressed because it is too large
Load Diff
75
libs/vkd3d-shader/make_spirv
Executable file
75
libs/vkd3d-shader/make_spirv
Executable file
@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
#
|
||||||
|
# Copyright 2025 Henri Verbeet
|
||||||
|
#
|
||||||
|
# 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.1 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, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use JSON;
|
||||||
|
use open ':utf8';
|
||||||
|
binmode STDOUT, ':utf8';
|
||||||
|
|
||||||
|
sub opcode_id($)
|
||||||
|
{
|
||||||
|
sprintf "0x%04x", shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub grammar_version($)
|
||||||
|
{
|
||||||
|
my ($grammar) = @_;
|
||||||
|
|
||||||
|
"$grammar->{major_version}.$grammar->{minor_version}.$grammar->{revision}";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub print_opcode_info(_)
|
||||||
|
{
|
||||||
|
my ($instruction) = @_;
|
||||||
|
my $operand_count = @{$instruction->{operands} // []};
|
||||||
|
|
||||||
|
print " {${\opcode_id $instruction->{opcode}}, \"$instruction->{opname}\", $operand_count},\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub print_header($)
|
||||||
|
{
|
||||||
|
my ($grammar) = @_;
|
||||||
|
|
||||||
|
print "/* This file is automatically generated from version ${\grammar_version $grammar} of the\n";
|
||||||
|
print " * machine-readable SPIR-V grammar.\n";
|
||||||
|
print " *\n";
|
||||||
|
print " * The original source is covered by the following license:\n";
|
||||||
|
print " *\n";
|
||||||
|
print map {" * $_" =~ s/ +$//r . "\n"} @{$grammar->{copyright}};
|
||||||
|
print " */\n\n";
|
||||||
|
|
||||||
|
print "static const struct spirv_parser_opcode_info\n";
|
||||||
|
print "{\n";
|
||||||
|
print " uint16_t op;\n";
|
||||||
|
print " const char *name;\n";
|
||||||
|
print " size_t operand_count;\n";
|
||||||
|
print "}\n";
|
||||||
|
print "spirv_parser_opcode_info[] =\n";
|
||||||
|
print "{\n";
|
||||||
|
print_opcode_info foreach sort {$a->{opcode} <=> $b->{opcode}} @{$grammar->{instructions}};
|
||||||
|
print "};\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
die "No input file specified.\n" unless @ARGV;
|
||||||
|
print_header do
|
||||||
|
{
|
||||||
|
local $/;
|
||||||
|
open my $fh, '<', $ARGV[0] or die $!;
|
||||||
|
decode_json <$fh>;
|
||||||
|
};
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "vkd3d_shader_private.h"
|
#include "vkd3d_shader_private.h"
|
||||||
|
#include "spirv_grammar.h"
|
||||||
#include "rbtree.h"
|
#include "rbtree.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -214,6 +215,7 @@ struct spirv_colours
|
|||||||
const char *reset;
|
const char *reset;
|
||||||
const char *comment;
|
const char *comment;
|
||||||
const char *literal;
|
const char *literal;
|
||||||
|
const char *opcode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct spirv_parser
|
struct spirv_parser
|
||||||
@ -310,6 +312,12 @@ static void spirv_parser_print_immediate_word(struct spirv_parser *parser,
|
|||||||
prefix, parser->colours.literal, w, parser->colours.reset, suffix);
|
prefix, parser->colours.literal, w, parser->colours.reset, suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void spirv_parser_print_opcode(struct spirv_parser *parser,
|
||||||
|
struct vkd3d_string_buffer *buffer, const char *name)
|
||||||
|
{
|
||||||
|
vkd3d_string_buffer_printf(buffer, "%s%s%s", parser->colours.opcode, name, parser->colours.reset);
|
||||||
|
}
|
||||||
|
|
||||||
static void spirv_parser_print_instruction_offset(struct spirv_parser *parser,
|
static void spirv_parser_print_instruction_offset(struct spirv_parser *parser,
|
||||||
struct vkd3d_string_buffer *buffer, const char *prefix, size_t offset, const char *suffix)
|
struct vkd3d_string_buffer *buffer, const char *prefix, size_t offset, const char *suffix)
|
||||||
{
|
{
|
||||||
@ -317,6 +325,20 @@ static void spirv_parser_print_instruction_offset(struct spirv_parser *parser,
|
|||||||
parser->colours.comment, offset * sizeof(uint32_t), parser->colours.reset, suffix);
|
parser->colours.comment, offset * sizeof(uint32_t), parser->colours.reset, suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int spirv_parser_opcode_info_compare(const void *key, const void *element)
|
||||||
|
{
|
||||||
|
const struct spirv_parser_opcode_info *e = element;
|
||||||
|
const uint16_t *op = key;
|
||||||
|
|
||||||
|
return vkd3d_u32_compare(*op, e->op);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct spirv_parser_opcode_info *spirv_parser_get_opcode_info(uint16_t op)
|
||||||
|
{
|
||||||
|
return bsearch(&op, spirv_parser_opcode_info, ARRAY_SIZE(spirv_parser_opcode_info),
|
||||||
|
sizeof(*spirv_parser_opcode_info), spirv_parser_opcode_info_compare);
|
||||||
|
}
|
||||||
|
|
||||||
static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser)
|
static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser)
|
||||||
{
|
{
|
||||||
uint32_t magic, version, generator, bound, schema;
|
uint32_t magic, version, generator, bound, schema;
|
||||||
@ -384,10 +406,26 @@ static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser)
|
|||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void spirv_parser_parse_raw_instruction(struct spirv_parser *parser, uint16_t count)
|
||||||
|
{
|
||||||
|
size_t pos = parser->pos;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (parser->formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT)
|
||||||
|
vkd3d_string_buffer_printf(parser->text, "%*s", VKD3D_SPIRV_INDENT, "");
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
spirv_parser_print_immediate_word(parser, parser->text, i ? " " : "", spirv_parser_read_u32(parser), "");
|
||||||
|
}
|
||||||
|
if (parser->formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_OFFSETS)
|
||||||
|
spirv_parser_print_instruction_offset(parser, parser->text, " ", pos, "");
|
||||||
|
vkd3d_string_buffer_printf(parser->text, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
static enum vkd3d_result spirv_parser_parse_instruction(struct spirv_parser *parser)
|
static enum vkd3d_result spirv_parser_parse_instruction(struct spirv_parser *parser)
|
||||||
{
|
{
|
||||||
|
const struct spirv_parser_opcode_info *info;
|
||||||
uint16_t op, count;
|
uint16_t op, count;
|
||||||
unsigned int i;
|
|
||||||
uint32_t word;
|
uint32_t word;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
|
|
||||||
@ -403,21 +441,32 @@ static enum vkd3d_result spirv_parser_parse_instruction(struct spirv_parser *par
|
|||||||
return VKD3D_ERROR_INVALID_SHADER;
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(info = spirv_parser_get_opcode_info(op)))
|
||||||
|
{
|
||||||
|
spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
|
||||||
|
"Unrecognised instruction %#x.", op);
|
||||||
|
goto raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->operand_count)
|
||||||
|
{
|
||||||
|
spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
|
||||||
|
"Operands for instruction \"%s\" not handled.", info->name);
|
||||||
|
goto raw;
|
||||||
|
}
|
||||||
|
|
||||||
if (parser->formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT)
|
if (parser->formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT)
|
||||||
vkd3d_string_buffer_printf(parser->text, "%*s", VKD3D_SPIRV_INDENT, "");
|
vkd3d_string_buffer_printf(parser->text, "%*s", VKD3D_SPIRV_INDENT, "");
|
||||||
spirv_parser_print_immediate_word(parser, parser->text, "", word, "");
|
spirv_parser_print_opcode(parser, parser->text, info->name);
|
||||||
|
|
||||||
--count;
|
|
||||||
for (i = 0; i < count; ++i)
|
|
||||||
{
|
|
||||||
spirv_parser_print_immediate_word(parser, parser->text, " ", spirv_parser_read_u32(parser), "");
|
|
||||||
}
|
|
||||||
if (parser->formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_OFFSETS)
|
if (parser->formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_OFFSETS)
|
||||||
spirv_parser_print_instruction_offset(parser, parser->text, " ", pos, "");
|
spirv_parser_print_instruction_offset(parser, parser->text, " ", pos, "");
|
||||||
vkd3d_string_buffer_printf(parser->text, "\n");
|
vkd3d_string_buffer_printf(parser->text, "\n");
|
||||||
|
|
||||||
spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
|
return VKD3D_OK;
|
||||||
"Unrecognised instruction %#x.", op);
|
|
||||||
|
raw:
|
||||||
|
parser->pos = pos;
|
||||||
|
spirv_parser_parse_raw_instruction(parser, count);
|
||||||
|
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
@ -473,12 +522,14 @@ static enum vkd3d_result spirv_parser_init(struct spirv_parser *parser, const st
|
|||||||
.reset = "",
|
.reset = "",
|
||||||
.comment = "",
|
.comment = "",
|
||||||
.literal = "",
|
.literal = "",
|
||||||
|
.opcode = "",
|
||||||
};
|
};
|
||||||
static const struct spirv_colours colours =
|
static const struct spirv_colours colours =
|
||||||
{
|
{
|
||||||
.reset = "\x1b[m",
|
.reset = "\x1b[m",
|
||||||
.comment = "\x1b[36m",
|
.comment = "\x1b[36m",
|
||||||
.literal = "\x1b[95m",
|
.literal = "\x1b[95m",
|
||||||
|
.opcode = "\x1b[96;1m",
|
||||||
};
|
};
|
||||||
|
|
||||||
memset(parser, 0, sizeof(*parser));
|
memset(parser, 0, sizeof(*parser));
|
||||||
|
7
m4/check-perl-module.m4
Normal file
7
m4/check-perl-module.m4
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
dnl VKD3D_PERL_MODULE(module, action-if-not-found)
|
||||||
|
AC_DEFUN([VKD3D_CHECK_PERL_MODULE],
|
||||||
|
[AC_MSG_CHECKING([for perl module $1])
|
||||||
|
AS_IF([$PERL -e "use $1;" 2>&AS_MESSAGE_LOG_FD],
|
||||||
|
[AC_MSG_RESULT([yes])],
|
||||||
|
[AC_MSG_RESULT([no])]
|
||||||
|
[$2])])
|
Loading…
x
Reference in New Issue
Block a user