blob: cba3de5fb0fac2bbeee92beabe7f094a4479779a [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) {
Cody Northrop1f3644e2015-05-05 09:42:33 -0600115 printf("file must be .spv, .vert, .geom, or .frag\n");
Cody Northropbc12f872015-04-29 13:22:07 -0600116 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]);
Cody Northrop1f3644e2015-05-05 09:42:33 -0600143 fflush(stdout);
Cody Northropbc12f872015-04-29 13:22:07 -0600144
145 void *shaderCode;
146 size_t size;
147
148 if (checkFileExt(argv[1], ".spv")) {
149 shaderCode = load_spv_file(argv[1], &size);
Cody Northropbc12f872015-04-29 13:22:07 -0600150 } else if (checkFileExt(argv[1], ".vert")) {
151 shaderCode = load_glsl_file(argv[1], &size, VK_SHADER_STAGE_VERTEX);
Cody Northrop1f3644e2015-05-05 09:42:33 -0600152 } else if (checkFileExt(argv[1], ".geom")) {
153 shaderCode = load_glsl_file(argv[1], &size, VK_SHADER_STAGE_GEOMETRY);
154 } else if (checkFileExt(argv[1], ".frag")) {
155 shaderCode = load_glsl_file(argv[1], &size, VK_SHADER_STAGE_FRAGMENT);
Cody Northropbc12f872015-04-29 13:22:07 -0600156 } else {
157 return EXIT_FAILURE;
158 }
159
160 assert(shaderCode);
161
162 struct intel_ir *shader_program = shader_create_ir(NULL, shaderCode, size);
163 assert(shader_program);
164
165 // Set up only the fields needed for backend compile
166 struct intel_gpu gpu = { 0 };
167 gpu.gen_opaque = INTEL_GEN(7.5);
168 gpu.gt = 3;
169
170 printf("Backend compile %s\n", argv[1]);
Cody Northrop1f3644e2015-05-05 09:42:33 -0600171 fflush(stdout);
Cody Northropbc12f872015-04-29 13:22:07 -0600172
173 // struct timespec before;
174 // clock_gettime(CLOCK_MONOTONIC, &before);
175 // uint64_t beforeNanoSeconds = before.tv_nsec + before.tv_sec*INT64_C(1000000000);
176
177 struct intel_pipeline_shader pipe_shader;
178 VkResult ret = intel_pipeline_shader_compile(&pipe_shader, &gpu, NULL, NULL, shader_program);
179
180 // struct timespec after;
181 // clock_gettime(CLOCK_MONOTONIC, &after);
182 // uint64_t afterNanoSeconds = after.tv_nsec + after.tv_sec*INT64_C(1000000000);
183 // printf("file: %s, intel_pipeline_shader_compile = %" PRIu64 " milliseconds\n", argv[1], (afterNanoSeconds - beforeNanoSeconds)/1000000);
184 // fflush(stdout);
185
186 if (ret != VK_SUCCESS)
187 return ret;
188
189 intel_pipeline_shader_cleanup(&pipe_shader, &gpu);
190 shader_destroy_ir(shader_program);
191 }
192 break;
193 case 3:
194 // Call vkCreateShader on both shaders, then call vkCreateGraphicsPipeline?
195 // Only need to hook this up if we start invoking the backend once for the whole pipeline
196
197 printf("Multiple shaders not hooked up yet\n");
198 break;
199
200 // Ensure both filenames have a .spv extension
201 if (!checkFileName(argv[1]))
202 return EXIT_FAILURE;
203
204 if (!checkFileName(argv[2]))
205 return EXIT_FAILURE;
206
207 void *shaderCode[2];
208 size_t size[2];
209 struct intel_ir *result[2];
210
211 // Compile first shader
212 shaderCode[0] = load_spv_file(argv[1], &size[0]);
213 assert(shaderCode[0]);
214 printf("Compiling %s\n", argv[1]);
215 result[0] = shader_create_ir(NULL, shaderCode[0], size[0]);
216 assert(result[0]);
217
218 // Compile second shader
219 shaderCode[1] = load_spv_file(argv[2], &size[1]);
220 assert(shaderCode[1]);
221 printf("Compiling %s\n", argv[2]);
222 result[1] = shader_create_ir(NULL, shaderCode[1], size[1]);
223 assert(result[1]);
224
225
226 shader_destroy_ir(result[0]);
227 shader_destroy_ir(result[1]);
228
229 break;
230 case 0:
231 case 1:
232 default:
233 printf("Please provide one .spv, .vert or .frag file as input\n");
234 break;
Cody Northrop0d5881e2014-09-17 14:06:55 -0600235 }
236
Cody Northrop0d5881e2014-09-17 14:06:55 -0600237 return status;
238}