blob: eb16b6c694e626913f585058eabcb0953f92ac00 [file] [log] [blame]
Cody Northrop0d5881e2014-09-17 14:06:55 -06001/*
2 * Copyright © 2008, 2009 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23#include <getopt.h>
Cody Northropbc12f872015-04-29 13:22:07 -060024#include <stdio.h>
25#include <stdlib.h>
26#include <assert.h>
27#include <string.h>
28#include <inttypes.h>
Cody Northrop0d5881e2014-09-17 14:06:55 -060029
30/** @file main.cpp
31 *
32 * This file is the main() routine and scaffolding for producing
33 * builtin_compiler (which doesn't include builtins itself and is used
34 * to generate the profile information for builtin_function.cpp), and
35 * for glsl_compiler (which does include builtins and can be used to
36 * offline compile GLSL code and examine the resulting GLSL IR.
37 */
38
Cody Northropbc12f872015-04-29 13:22:07 -060039#include "gpu.h"
40#include "pipeline.h"
41#include "compiler_interface.h"
42#include "compiler/mesa-utils/src/glsl/ralloc.h"
43#include "pipeline_compiler_interface.h"
Cody Northrop0d5881e2014-09-17 14:06:55 -060044
Cody Northrop0d5881e2014-09-17 14:06:55 -060045
Cody Northropbc12f872015-04-29 13:22:07 -060046static char* load_spv_file(const char *filename, size_t *psize)
Cody Northrop0d5881e2014-09-17 14:06:55 -060047{
Cody Northropbc12f872015-04-29 13:22:07 -060048 long int size;
49 void *shader_code;
Cody Northrop0d5881e2014-09-17 14:06:55 -060050
Cody Northropbc12f872015-04-29 13:22:07 -060051 FILE *fp = fopen(filename, "rb");
52 if (!fp) return NULL;
Cody Northrop0d5881e2014-09-17 14:06:55 -060053
Cody Northropbc12f872015-04-29 13:22:07 -060054 fseek(fp, 0L, SEEK_END);
55 size = ftell(fp);
Cody Northrop0d5881e2014-09-17 14:06:55 -060056
Cody Northropbc12f872015-04-29 13:22:07 -060057 fseek(fp, 0L, SEEK_SET);
Cody Northrop0d5881e2014-09-17 14:06:55 -060058
Cody Northropbc12f872015-04-29 13:22:07 -060059 shader_code = malloc(size);
60 fread(shader_code, size, 1, fp);
Cody Northrop0d5881e2014-09-17 14:06:55 -060061
Cody Northropbc12f872015-04-29 13:22:07 -060062 *psize = size;
Cody Northrop0d5881e2014-09-17 14:06:55 -060063
Cody Northropbc12f872015-04-29 13:22:07 -060064 return (char *) shader_code;
Cody Northrop0d5881e2014-09-17 14:06:55 -060065}
66
Cody Northropbc12f872015-04-29 13:22:07 -060067
68static char* load_glsl_file(const char *filename, size_t *psize, VkShaderStage stage)
Cody Northrop0d5881e2014-09-17 14:06:55 -060069{
Cody Northropbc12f872015-04-29 13:22:07 -060070 long int size;
71 void *shader_code;
Cody Northrop0d5881e2014-09-17 14:06:55 -060072
Cody Northropbc12f872015-04-29 13:22:07 -060073 FILE *fp = fopen(filename, "r");
74 if (!fp) return NULL;
Cody Northrop0d5881e2014-09-17 14:06:55 -060075
Cody Northropbc12f872015-04-29 13:22:07 -060076 fseek(fp, 0L, SEEK_END);
77 size = ftell(fp) + sizeof(icd_spv_header) + 1;
Cody Northrop0d5881e2014-09-17 14:06:55 -060078
Cody Northropbc12f872015-04-29 13:22:07 -060079 fseek(fp, 0L, SEEK_SET);
Cody Northrop0d5881e2014-09-17 14:06:55 -060080
Cody Northropbc12f872015-04-29 13:22:07 -060081 shader_code = malloc(size);
82 fread((char *)shader_code + sizeof(icd_spv_header), size - sizeof(icd_spv_header), 1, fp);
83 ((char *)shader_code)[size-1] = 0;
Cody Northrop0d5881e2014-09-17 14:06:55 -060084
Cody Northropbc12f872015-04-29 13:22:07 -060085 icd_spv_header* header = (icd_spv_header*)shader_code;
86 header->magic = ICD_SPV_MAGIC;
87 header->version = 0; // not SPV
88 header->gen_magic = stage;
Cody Northrop0d5881e2014-09-17 14:06:55 -060089
Cody Northropbc12f872015-04-29 13:22:07 -060090 *psize = size;
Cody Northrop0d5881e2014-09-17 14:06:55 -060091
Cody Northropbc12f872015-04-29 13:22:07 -060092 return (char *) shader_code;
Cody Northrop0d5881e2014-09-17 14:06:55 -060093}
94
95int dump_ast = 0;
96int dump_hir = 0;
97int dump_lir = 0;
98int do_link = 0;
99
100const struct option compiler_opts[] = {
101 { "dump-ast", no_argument, &dump_ast, 1 },
102 { "dump-hir", no_argument, &dump_hir, 1 },
103 { "dump-lir", no_argument, &dump_lir, 1 },
104 { "link", no_argument, &do_link, 1 },
105 { "version", required_argument, NULL, 'v' },
106 { NULL, 0, NULL, 0 }
107};
108
Cody Northrop0d5881e2014-09-17 14:06:55 -0600109
Cody Northropbc12f872015-04-29 13:22:07 -0600110bool checkFileName(char* fileName)
111{
112 const unsigned fileNameLength = strlen(fileName);
113 if (fileNameLength < 5 ||
114 strncmp(".spv", &fileName[fileNameLength - 4], 4) != 0) {
115 printf("file must be .spv, .vert or .frag\n");
116 return false;
117 }
118
119 return true;
Cody Northrop0d5881e2014-09-17 14:06:55 -0600120}
121
Cody Northropbc12f872015-04-29 13:22:07 -0600122
123bool checkFileExt(char* fileName, const char* ext)
Cody Northrop0d5881e2014-09-17 14:06:55 -0600124{
Cody Northropbc12f872015-04-29 13:22:07 -0600125 const unsigned fileNameLength = strlen(fileName);
126 if (strncmp(ext, &fileName[fileNameLength - strlen(ext)], strlen(ext)) != 0) {
127 return false;
128 }
129
130 return true;
Cody Northrop0d5881e2014-09-17 14:06:55 -0600131}
132
Cody Northropbc12f872015-04-29 13:22:07 -0600133int main(int argc, char **argv)
Cody Northrop0d5881e2014-09-17 14:06:55 -0600134{
135 int status = EXIT_SUCCESS;
Cody Northrop0d5881e2014-09-17 14:06:55 -0600136
Cody Northropbc12f872015-04-29 13:22:07 -0600137 switch (argc) {
138 case 2:
139 {
140 // Call vkCreateShader on the single shader
141
142 printf("Frontend compile %s\n", argv[1]);
143
144 void *shaderCode;
145 size_t size;
146
147 if (checkFileExt(argv[1], ".spv")) {
148 shaderCode = load_spv_file(argv[1], &size);
149 } else if (checkFileExt(argv[1], ".frag")) {
150 shaderCode = load_glsl_file(argv[1], &size, VK_SHADER_STAGE_FRAGMENT);
151 } else if (checkFileExt(argv[1], ".vert")) {
152 shaderCode = load_glsl_file(argv[1], &size, VK_SHADER_STAGE_VERTEX);
153 } else {
154 return EXIT_FAILURE;
155 }
156
157 assert(shaderCode);
158
159 struct intel_ir *shader_program = shader_create_ir(NULL, shaderCode, size);
160 assert(shader_program);
161
162 // Set up only the fields needed for backend compile
163 struct intel_gpu gpu = { 0 };
164 gpu.gen_opaque = INTEL_GEN(7.5);
165 gpu.gt = 3;
166
167 printf("Backend compile %s\n", argv[1]);
168
169 // struct timespec before;
170 // clock_gettime(CLOCK_MONOTONIC, &before);
171 // uint64_t beforeNanoSeconds = before.tv_nsec + before.tv_sec*INT64_C(1000000000);
172
173 struct intel_pipeline_shader pipe_shader;
174 VkResult ret = intel_pipeline_shader_compile(&pipe_shader, &gpu, NULL, NULL, shader_program);
175
176 // struct timespec after;
177 // clock_gettime(CLOCK_MONOTONIC, &after);
178 // uint64_t afterNanoSeconds = after.tv_nsec + after.tv_sec*INT64_C(1000000000);
179 // printf("file: %s, intel_pipeline_shader_compile = %" PRIu64 " milliseconds\n", argv[1], (afterNanoSeconds - beforeNanoSeconds)/1000000);
180 // fflush(stdout);
181
182 if (ret != VK_SUCCESS)
183 return ret;
184
185 intel_pipeline_shader_cleanup(&pipe_shader, &gpu);
186 shader_destroy_ir(shader_program);
187 }
188 break;
189 case 3:
190 // Call vkCreateShader on both shaders, then call vkCreateGraphicsPipeline?
191 // Only need to hook this up if we start invoking the backend once for the whole pipeline
192
193 printf("Multiple shaders not hooked up yet\n");
194 break;
195
196 // Ensure both filenames have a .spv extension
197 if (!checkFileName(argv[1]))
198 return EXIT_FAILURE;
199
200 if (!checkFileName(argv[2]))
201 return EXIT_FAILURE;
202
203 void *shaderCode[2];
204 size_t size[2];
205 struct intel_ir *result[2];
206
207 // Compile first shader
208 shaderCode[0] = load_spv_file(argv[1], &size[0]);
209 assert(shaderCode[0]);
210 printf("Compiling %s\n", argv[1]);
211 result[0] = shader_create_ir(NULL, shaderCode[0], size[0]);
212 assert(result[0]);
213
214 // Compile second shader
215 shaderCode[1] = load_spv_file(argv[2], &size[1]);
216 assert(shaderCode[1]);
217 printf("Compiling %s\n", argv[2]);
218 result[1] = shader_create_ir(NULL, shaderCode[1], size[1]);
219 assert(result[1]);
220
221
222 shader_destroy_ir(result[0]);
223 shader_destroy_ir(result[1]);
224
225 break;
226 case 0:
227 case 1:
228 default:
229 printf("Please provide one .spv, .vert or .frag file as input\n");
230 break;
Cody Northrop0d5881e2014-09-17 14:06:55 -0600231 }
232
Cody Northrop0d5881e2014-09-17 14:06:55 -0600233 return status;
234}