Path: blob/21.2-virgl/src/compiler/spirv/spirv2nir.c
4545 views
/*1* Copyright © 2015 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*22* Authors:23* Jason Ekstrand ([email protected])24*25*/2627/*28* A simple executable that opens a SPIR-V shader, converts it to NIR, and29* dumps out the result. This should be useful for testing the30* spirv_to_nir code.31*/3233#include "spirv/nir_spirv.h"3435#include <sys/mman.h>36#include <sys/types.h>37#include <fcntl.h>38#include <unistd.h>39#include <stdio.h>40#include <errno.h>41#include <string.h>42#include <getopt.h>4344#define WORD_SIZE 44546static gl_shader_stage47stage_to_enum(char *stage)48{49if (!strcmp(stage, "vertex"))50return MESA_SHADER_VERTEX;51else if (!strcmp(stage, "tess-ctrl"))52return MESA_SHADER_TESS_CTRL;53else if (!strcmp(stage, "tess-eval"))54return MESA_SHADER_TESS_EVAL;55else if (!strcmp(stage, "geometry"))56return MESA_SHADER_GEOMETRY;57else if (!strcmp(stage, "fragment"))58return MESA_SHADER_FRAGMENT;59else if (!strcmp(stage, "compute"))60return MESA_SHADER_COMPUTE;61else if (!strcmp(stage, "kernel"))62return MESA_SHADER_KERNEL;63else64return MESA_SHADER_NONE;65}6667static void68print_usage(char *exec_name, FILE *f)69{70fprintf(f,71"Usage: %s [options] file\n"72"Options:\n"73" -h --help Print this help.\n"74" -s, --stage <stage> Specify the shader stage. Valid stages are:\n"75" vertex, tess-ctrl, tess-eval, geometry, fragment,\n"76" compute, and kernel (OpenCL-style compute).\n"77" -e, --entry <name> Specify the entry-point name.\n"78" -g, --opengl Use OpenGL environment instead of Vulkan for\n"79" graphics stages.\n"80, exec_name);81}8283int main(int argc, char **argv)84{85gl_shader_stage shader_stage = MESA_SHADER_FRAGMENT;86char *entry_point = "main";87int ch;88enum nir_spirv_execution_environment env = NIR_SPIRV_VULKAN;8990static struct option long_options[] =91{92{"help", no_argument, 0, 'h'},93{"stage", required_argument, 0, 's'},94{"entry", required_argument, 0, 'e'},95{"opengl", no_argument, 0, 'g'},96{0, 0, 0, 0}97};9899while ((ch = getopt_long(argc, argv, "hs:e:g", long_options, NULL)) != -1)100{101switch (ch)102{103case 'h':104print_usage(argv[0], stdout);105return 0;106case 's':107shader_stage = stage_to_enum(optarg);108if (shader_stage == MESA_SHADER_NONE)109{110fprintf(stderr, "Unknown stage \"%s\"\n", optarg);111print_usage(argv[0], stderr);112return 1;113}114break;115case 'e':116entry_point = optarg;117break;118case 'g':119env = NIR_SPIRV_OPENGL;120break;121default:122fprintf(stderr, "Unrecognized option \"%s\".\n", optarg);123print_usage(argv[0], stderr);124return 1;125}126}127128const char *filename = argv[optind];129int fd = open(filename, O_RDONLY);130if (fd < 0)131{132fprintf(stderr, "Failed to open %s\n", filename);133return 1;134}135136off_t len = lseek(fd, 0, SEEK_END);137if (len % WORD_SIZE != 0)138{139fprintf(stderr, "File length isn't a multiple of the word size\n");140fprintf(stderr, "Are you sure this is a valid SPIR-V shader?\n");141close(fd);142return 1;143}144145size_t word_count = len / WORD_SIZE;146147const void *map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);148if (map == MAP_FAILED)149{150fprintf(stderr, "Failed to mmap the file: errno=%d, %s\n",151errno, strerror(errno));152close(fd);153return 1;154}155156glsl_type_singleton_init_or_ref();157158struct spirv_to_nir_options spirv_opts = {159.environment = env,160.use_deref_buffer_array_length = env == NIR_SPIRV_OPENGL,161};162163if (shader_stage == MESA_SHADER_KERNEL) {164spirv_opts.environment = NIR_SPIRV_OPENCL;165spirv_opts.caps.address = true;166spirv_opts.caps.float64 = true;167spirv_opts.caps.int8 = true;168spirv_opts.caps.int16 = true;169spirv_opts.caps.int64 = true;170spirv_opts.caps.kernel = true;171}172173nir_shader *nir = spirv_to_nir(map, word_count, NULL, 0,174shader_stage, entry_point,175&spirv_opts, NULL);176177if (nir)178nir_print_shader(nir, stderr);179else180fprintf(stderr, "SPIRV to NIR compilation failed\n");181182glsl_type_singleton_decref();183184return 0;185}186187188