1/* 2 * Copyright © 2015 Intel Corporation 3 * Copyright © Microsoft Corporation 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 */ 24 25/* 26 * A simple executable that opens a SPIR-V shader, converts it to DXIL via 27 * NIR, and dumps out the result. This should be useful for testing the 28 * nir_to_dxil code. Based on spirv2nir.c. 29 */ 30 31#include "nir_to_dxil.h" 32#include "spirv/nir_spirv.h" 33#include "spirv_to_dxil.h" 34 35#include "util/os_file.h" 36#include <errno.h> 37#include <getopt.h> 38#include <stdio.h> 39#include <string.h> 40 41#define WORD_SIZE 4 42 43static gl_shader_stage 44stage_to_enum(char *stage) 45{ 46 if (!strcmp(stage, "vertex")) 47 return MESA_SHADER_VERTEX; 48 else if (!strcmp(stage, "tess-ctrl")) 49 return MESA_SHADER_TESS_CTRL; 50 else if (!strcmp(stage, "tess-eval")) 51 return MESA_SHADER_TESS_EVAL; 52 else if (!strcmp(stage, "geometry")) 53 return MESA_SHADER_GEOMETRY; 54 else if (!strcmp(stage, "fragment")) 55 return MESA_SHADER_FRAGMENT; 56 else if (!strcmp(stage, "compute")) 57 return MESA_SHADER_COMPUTE; 58 else if (!strcmp(stage, "kernel")) 59 return MESA_SHADER_KERNEL; 60 else 61 return MESA_SHADER_NONE; 62} 63 64int 65main(int argc, char **argv) 66{ 67 gl_shader_stage shader_stage = MESA_SHADER_FRAGMENT; 68 char *entry_point = "main"; 69 char *output_file = ""; 70 int ch; 71 72 static struct option long_options[] = { 73 {"stage", required_argument, 0, 's'}, 74 {"entry", required_argument, 0, 'e'}, 75 {"output", required_argument, 0, 'o'}, 76 {0, 0, 0, 0}}; 77 78 while ((ch = getopt_long(argc, argv, "s:e:o:", long_options, NULL)) != 79 -1) { 80 switch (ch) { 81 case 's': 82 shader_stage = stage_to_enum(optarg); 83 if (shader_stage == MESA_SHADER_NONE) { 84 fprintf(stderr, "Unknown stage %s\n", optarg); 85 return 1; 86 } 87 break; 88 case 'e': 89 entry_point = optarg; 90 break; 91 case 'o': 92 output_file = optarg; 93 break; 94 default: 95 fprintf(stderr, "Unrecognized option.\n"); 96 return 1; 97 } 98 } 99 100 if (optind != argc - 1) { 101 if (optind < argc) 102 fprintf(stderr, "Please specify only one input file."); 103 else 104 fprintf(stderr, "Please specify an input file."); 105 return 1; 106 } 107 108 const char *filename = argv[optind]; 109 size_t file_size; 110 char *file_contents = os_read_file(filename, &file_size); 111 if (!file_contents) { 112 fprintf(stderr, "Failed to open %s\n", filename); 113 return 1; 114 } 115 116 if (file_size % WORD_SIZE != 0) { 117 fprintf(stderr, "%s size == %zu is not a multiple of %d\n", filename, 118 file_size, WORD_SIZE); 119 return 1; 120 } 121 122 size_t word_count = file_size / WORD_SIZE; 123 124 struct dxil_spirv_runtime_conf conf; 125 memset(&conf, 0, sizeof(conf)); 126 conf.runtime_data_cbv.base_shader_register = 0; 127 conf.runtime_data_cbv.register_space = 31; 128 conf.zero_based_vertex_instance_id = true; 129 130 struct dxil_spirv_object obj; 131 memset(&obj, 0, sizeof(obj)); 132 if (spirv_to_dxil((uint32_t *)file_contents, word_count, NULL, 0, 133 (dxil_spirv_shader_stage)shader_stage, entry_point, 134 &conf, &obj)) { 135 FILE *file = fopen(output_file, "wb"); 136 if (!file) { 137 fprintf(stderr, "Failed to open %s, %s\n", output_file, 138 strerror(errno)); 139 spirv_to_dxil_free(&obj); 140 free(file_contents); 141 return 1; 142 } 143 144 fwrite(obj.binary.buffer, sizeof(char), obj.binary.size, file); 145 fclose(file); 146 spirv_to_dxil_free(&obj); 147 } else { 148 fprintf(stderr, "Compilation failed\n"); 149 return 1; 150 } 151 152 free(file_contents); 153 154 return 0; 155} 156