17ec681f3Smrg/* 27ec681f3Smrg * Copyright © 2015 Intel Corporation 37ec681f3Smrg * Copyright © Microsoft Corporation 47ec681f3Smrg * 57ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 67ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 77ec681f3Smrg * to deal in the Software without restriction, including without limitation 87ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 97ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 107ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 117ec681f3Smrg * 127ec681f3Smrg * The above copyright notice and this permission notice (including the next 137ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 147ec681f3Smrg * Software. 157ec681f3Smrg * 167ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 177ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 187ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 197ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 207ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 217ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 227ec681f3Smrg * IN THE SOFTWARE. 237ec681f3Smrg */ 247ec681f3Smrg 257ec681f3Smrg/* 267ec681f3Smrg * A simple executable that opens a SPIR-V shader, converts it to DXIL via 277ec681f3Smrg * NIR, and dumps out the result. This should be useful for testing the 287ec681f3Smrg * nir_to_dxil code. Based on spirv2nir.c. 297ec681f3Smrg */ 307ec681f3Smrg 317ec681f3Smrg#include "nir_to_dxil.h" 327ec681f3Smrg#include "spirv/nir_spirv.h" 337ec681f3Smrg#include "spirv_to_dxil.h" 347ec681f3Smrg 357ec681f3Smrg#include "util/os_file.h" 367ec681f3Smrg#include <errno.h> 377ec681f3Smrg#include <getopt.h> 387ec681f3Smrg#include <stdio.h> 397ec681f3Smrg#include <string.h> 407ec681f3Smrg 417ec681f3Smrg#define WORD_SIZE 4 427ec681f3Smrg 437ec681f3Smrgstatic gl_shader_stage 447ec681f3Smrgstage_to_enum(char *stage) 457ec681f3Smrg{ 467ec681f3Smrg if (!strcmp(stage, "vertex")) 477ec681f3Smrg return MESA_SHADER_VERTEX; 487ec681f3Smrg else if (!strcmp(stage, "tess-ctrl")) 497ec681f3Smrg return MESA_SHADER_TESS_CTRL; 507ec681f3Smrg else if (!strcmp(stage, "tess-eval")) 517ec681f3Smrg return MESA_SHADER_TESS_EVAL; 527ec681f3Smrg else if (!strcmp(stage, "geometry")) 537ec681f3Smrg return MESA_SHADER_GEOMETRY; 547ec681f3Smrg else if (!strcmp(stage, "fragment")) 557ec681f3Smrg return MESA_SHADER_FRAGMENT; 567ec681f3Smrg else if (!strcmp(stage, "compute")) 577ec681f3Smrg return MESA_SHADER_COMPUTE; 587ec681f3Smrg else if (!strcmp(stage, "kernel")) 597ec681f3Smrg return MESA_SHADER_KERNEL; 607ec681f3Smrg else 617ec681f3Smrg return MESA_SHADER_NONE; 627ec681f3Smrg} 637ec681f3Smrg 647ec681f3Smrgint 657ec681f3Smrgmain(int argc, char **argv) 667ec681f3Smrg{ 677ec681f3Smrg gl_shader_stage shader_stage = MESA_SHADER_FRAGMENT; 687ec681f3Smrg char *entry_point = "main"; 697ec681f3Smrg char *output_file = ""; 707ec681f3Smrg int ch; 717ec681f3Smrg 727ec681f3Smrg static struct option long_options[] = { 737ec681f3Smrg {"stage", required_argument, 0, 's'}, 747ec681f3Smrg {"entry", required_argument, 0, 'e'}, 757ec681f3Smrg {"output", required_argument, 0, 'o'}, 767ec681f3Smrg {0, 0, 0, 0}}; 777ec681f3Smrg 787ec681f3Smrg while ((ch = getopt_long(argc, argv, "s:e:o:", long_options, NULL)) != 797ec681f3Smrg -1) { 807ec681f3Smrg switch (ch) { 817ec681f3Smrg case 's': 827ec681f3Smrg shader_stage = stage_to_enum(optarg); 837ec681f3Smrg if (shader_stage == MESA_SHADER_NONE) { 847ec681f3Smrg fprintf(stderr, "Unknown stage %s\n", optarg); 857ec681f3Smrg return 1; 867ec681f3Smrg } 877ec681f3Smrg break; 887ec681f3Smrg case 'e': 897ec681f3Smrg entry_point = optarg; 907ec681f3Smrg break; 917ec681f3Smrg case 'o': 927ec681f3Smrg output_file = optarg; 937ec681f3Smrg break; 947ec681f3Smrg default: 957ec681f3Smrg fprintf(stderr, "Unrecognized option.\n"); 967ec681f3Smrg return 1; 977ec681f3Smrg } 987ec681f3Smrg } 997ec681f3Smrg 1007ec681f3Smrg if (optind != argc - 1) { 1017ec681f3Smrg if (optind < argc) 1027ec681f3Smrg fprintf(stderr, "Please specify only one input file."); 1037ec681f3Smrg else 1047ec681f3Smrg fprintf(stderr, "Please specify an input file."); 1057ec681f3Smrg return 1; 1067ec681f3Smrg } 1077ec681f3Smrg 1087ec681f3Smrg const char *filename = argv[optind]; 1097ec681f3Smrg size_t file_size; 1107ec681f3Smrg char *file_contents = os_read_file(filename, &file_size); 1117ec681f3Smrg if (!file_contents) { 1127ec681f3Smrg fprintf(stderr, "Failed to open %s\n", filename); 1137ec681f3Smrg return 1; 1147ec681f3Smrg } 1157ec681f3Smrg 1167ec681f3Smrg if (file_size % WORD_SIZE != 0) { 1177ec681f3Smrg fprintf(stderr, "%s size == %zu is not a multiple of %d\n", filename, 1187ec681f3Smrg file_size, WORD_SIZE); 1197ec681f3Smrg return 1; 1207ec681f3Smrg } 1217ec681f3Smrg 1227ec681f3Smrg size_t word_count = file_size / WORD_SIZE; 1237ec681f3Smrg 1247ec681f3Smrg struct dxil_spirv_runtime_conf conf; 1257ec681f3Smrg memset(&conf, 0, sizeof(conf)); 1267ec681f3Smrg conf.runtime_data_cbv.base_shader_register = 0; 1277ec681f3Smrg conf.runtime_data_cbv.register_space = 31; 1287ec681f3Smrg conf.zero_based_vertex_instance_id = true; 1297ec681f3Smrg 1307ec681f3Smrg struct dxil_spirv_object obj; 1317ec681f3Smrg memset(&obj, 0, sizeof(obj)); 1327ec681f3Smrg if (spirv_to_dxil((uint32_t *)file_contents, word_count, NULL, 0, 1337ec681f3Smrg (dxil_spirv_shader_stage)shader_stage, entry_point, 1347ec681f3Smrg &conf, &obj)) { 1357ec681f3Smrg FILE *file = fopen(output_file, "wb"); 1367ec681f3Smrg if (!file) { 1377ec681f3Smrg fprintf(stderr, "Failed to open %s, %s\n", output_file, 1387ec681f3Smrg strerror(errno)); 1397ec681f3Smrg spirv_to_dxil_free(&obj); 1407ec681f3Smrg free(file_contents); 1417ec681f3Smrg return 1; 1427ec681f3Smrg } 1437ec681f3Smrg 1447ec681f3Smrg fwrite(obj.binary.buffer, sizeof(char), obj.binary.size, file); 1457ec681f3Smrg fclose(file); 1467ec681f3Smrg spirv_to_dxil_free(&obj); 1477ec681f3Smrg } else { 1487ec681f3Smrg fprintf(stderr, "Compilation failed\n"); 1497ec681f3Smrg return 1; 1507ec681f3Smrg } 1517ec681f3Smrg 1527ec681f3Smrg free(file_contents); 1537ec681f3Smrg 1547ec681f3Smrg return 0; 1557ec681f3Smrg} 156