| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081 |
- // Simple text processing tool for converting shaders at runtime.
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include <string.h>
- #include "iron_string.h"
- #ifdef __linux__
- int krafix_compile(const char *source, char *output, int *length, const char *targetlang, const char *system, const char *shadertype, int version);
- #endif
- #ifdef _WIN32
- #include <d3d11.h>
- #include <D3Dcompiler.h>
- static void write_attrib(char *file, int *output_len, const char *attrib, int index) {
- if (index > -1) {
- strcpy(file + (*output_len), attrib);
- (*output_len) += strlen(attrib);
- file[(*output_len)] = 0;
- (*output_len) += 1;
- file[(*output_len)] = index;
- (*output_len) += 1;
- }
- }
- char *hlsl_to_bin(char *source, char *shader_type, char *to) {
- char *type;
- if (string_equals(shader_type, "vert")) {
- type = "vs_5_0";
- }
- else if (string_equals(shader_type, "frag")) {
- type = "ps_5_0";
- }
- else {
- type = "gs_5_0";
- }
- ID3DBlob *error_message;
- ID3DBlob *shader_buffer;
- // UINT flags = D3DCOMPILE_SKIP_OPTIMIZATION | D3DCOMPILE_SKIP_VALIDATION;
- UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL3;
- HRESULT hr = D3DCompile(source, strlen(source) + 1, NULL, NULL, NULL, "main", type, flags, 0, &shader_buffer, &error_message);
- if (hr != S_OK) {
- printf("%s\n", (char *)error_message->lpVtbl->GetBufferPointer(error_message));
- return NULL;
- }
- ID3D11ShaderReflection *reflector = NULL;
- D3DReflect(shader_buffer->lpVtbl->GetBufferPointer(shader_buffer), shader_buffer->lpVtbl->GetBufferSize(shader_buffer), &IID_ID3D11ShaderReflection, (void **)&reflector);
- int len = shader_buffer->lpVtbl->GetBufferSize(shader_buffer);
- char *file = malloc(len * 2);
- int output_len = 0;
- bool has_bone = strstr(source, " bone:") != NULL;
- bool has_col = strstr(source, " col:") != NULL;
- bool has_nor = strstr(source, " nor:") != NULL;
- bool has_pos = strstr(source, " pos:") != NULL;
- bool has_tex = strstr(source, " tex:") != NULL;
- int ibone = -1;
- int icol = -1;
- int inor = -1;
- int ipos = -1;
- int itex = -1;
- int iweight = -1;
- int index = 0;
- if (has_bone) ibone = index++;
- if (has_col) icol = index++;
- if (has_nor) inor = index++;
- if (has_pos) ipos = index++;
- if (has_tex) itex = index++;
- if (has_bone) iweight = index++;
- file[output_len] = (char)index;
- output_len += 1;
- write_attrib(file, &output_len, "bone", ibone);
- write_attrib(file, &output_len, "col", icol);
- write_attrib(file, &output_len, "nor", inor);
- write_attrib(file, &output_len, "pos", ipos);
- write_attrib(file, &output_len, "tex", itex);
- write_attrib(file, &output_len, "weight", iweight);
- D3D11_SHADER_DESC desc;
- reflector->lpVtbl->GetDesc(reflector, &desc);
- file[output_len] = desc.BoundResources;
- output_len += 1;
- for (int i = 0; i < desc.BoundResources; ++i) {
- D3D11_SHADER_INPUT_BIND_DESC bindDesc;
- reflector->lpVtbl->GetResourceBindingDesc(reflector, i, &bindDesc);
- strcpy(file + output_len, bindDesc.Name);
- output_len += strlen(bindDesc.Name);
- file[output_len] = 0;
- output_len += 1;
- file[output_len] = bindDesc.BindPoint;
- output_len += 1;
- }
- ID3D11ShaderReflectionConstantBuffer *constants = reflector->lpVtbl->GetConstantBufferByName(reflector, "$Globals");
- D3D11_SHADER_BUFFER_DESC buffer_desc;
- hr = constants->lpVtbl->GetDesc(constants, &buffer_desc);
- if (hr == S_OK) {
- file[output_len] = buffer_desc.Variables;
- output_len += 1;
- for (int i = 0; i < buffer_desc.Variables; ++i) {
- ID3D11ShaderReflectionVariable *variable = constants->lpVtbl->GetVariableByIndex(constants, i);
- D3D11_SHADER_VARIABLE_DESC variable_desc;
- hr = variable->lpVtbl->GetDesc(variable, &variable_desc);
- if (hr == S_OK) {
- strcpy(file + output_len, variable_desc.Name);
- output_len += strlen(variable_desc.Name);
- file[output_len] = 0;
- output_len += 1;
- *(uint32_t *)(file + output_len) = variable_desc.StartOffset;
- output_len += 4;
- *(uint32_t *)(file + output_len) = variable_desc.Size;
- output_len += 4;
- D3D11_SHADER_TYPE_DESC type_desc;
- ID3D11ShaderReflectionType *type = variable->lpVtbl->GetType(variable);
- hr = type->lpVtbl->GetDesc(type, &type_desc);
- if (hr == S_OK) {
- file[output_len] = type_desc.Columns;
- output_len += 1;
- file[output_len] = type_desc.Rows;
- output_len += 1;
- }
- else {
- file[output_len] = 0;
- output_len += 1;
- file[output_len] = 0;
- output_len += 1;
- }
- }
- }
- }
- else {
- file[output_len] = 0;
- output_len += 1;
- }
- memcpy(file + output_len, (char *)shader_buffer->lpVtbl->GetBufferPointer(shader_buffer), shader_buffer->lpVtbl->GetBufferSize(shader_buffer));
- output_len += shader_buffer->lpVtbl->GetBufferSize(shader_buffer);
- shader_buffer->lpVtbl->Release(shader_buffer);
- reflector->lpVtbl->Release(reflector);
- FILE *fp = fopen(to, "wb");
- fwrite(file, 1, output_len, fp);
- fclose(fp);
- free(file);
- }
- void hlslbin(const char *from, const char *to) {
- FILE *fp = fopen(from, "rb");
- fseek(fp , 0, SEEK_END);
- int size = ftell(fp);
- rewind(fp);
- char *source = malloc(size + 1);
- source[size] = 0;
- fread(source, size, 1, fp);
- fclose(fp);
- char *type;
- if (strstr(from, ".vert.")) {
- type = "vert";
- }
- else if (strstr(from, ".frag.")) {
- type = "frag";
- }
- else {
- type = "geom";
- }
- hlsl_to_bin(source, type, to);
- }
- #endif
- static char out[128 * 1024];
- static int out_pos = 0;
- static char line[1024];
- static char tmp[1024];
- static char *buffer;
- static int buffer_size;
- static int buffer_pos = 0;
- typedef struct var {
- char name[64];
- char type[16];
- } var_t;
- static char defines[32][64];
- static int defines_count;
- static bool is_defined[8];
- static int is_defined_index;
- static char *numbers[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
- static var_t inputs[8];
- static var_t outputs[8];
- static var_t uniforms[32];
- static var_t samplers[32];
- static int inputs_count;
- static int outputs_count;
- static int uniforms_count;
- static int samplers_count;
- static char *shader_type;
- const char *version_glsl = "#version 450\n";
- const char *version_essl = "#version 300 es\n";
- const char *precision_essl = "precision highp float;\nprecision mediump int;\n";
- const char *header_glsl = "#define GLSL\n\
- #define mul(a, b) b * a\n\
- #define atan2(x, y) atan(y, x)\n\
- #define OUT(t, v) out t v\n\
- ";
- const char *header_hlsl = "#define HLSL\n\
- #define sampler2D Texture2D\n\
- #define sampler3D Texture3D\n\
- #define texture(tex, coord) tex.Sample(tex ## _sampler, coord)\n\
- #define textureLod(tex, coord, lod) tex.SampleLevel(tex ## _sampler, coord, lod)\n\
- #define texelFetch(tex, coord, lod) tex.Load(float3(coord.xy, lod))\n\
- uint2 _GetDimensions(Texture2D tex, uint lod) { uint x, y; tex.GetDimensions(x, y); return uint2(x, y); }\n\
- #define textureSize _GetDimensions\n\
- #define mod(a, b) (a % b)\n\
- #define vec2 float2\n\
- #define vec3 float3\n\
- #define vec4 float4\n\
- #define ivec2 int2\n\
- #define ivec3 int3\n\
- #define ivec4 int4\n\
- #define mat2 float2x2\n\
- #define mat3 float3x3\n\
- #define mat4 float4x4\n\
- #define dFdx ddx\n\
- #define dFdy ddy\n\
- #define inversesqrt rsqrt\n\
- #define fract frac\n\
- #define mix lerp\n\
- #define OUT(t, v) out t v\n\
- ";
- const char *header_msl = "// my_main\n\
- #define METAL\n\
- #include <metal_stdlib>\n\
- #include <simd/simd.h>\n\
- using namespace metal;\n\
- #define sampler2D texture2d<float>\n\
- #define sampler3D texture3d<float>\n\
- #define texture(tex, coord) tex.sample(tex ## _sampler, coord)\n\
- #define textureLod(tex, coord, lod) tex.sample(tex ## _sampler, coord, level(lod))\n\
- #define texelFetch(tex, coord, lod) tex.read(uint2(coord), uint(lod))\n\
- float2 _getDimensions(texture2d<float> tex, uint lod) { return float2(tex.get_width(lod), tex.get_height(lod)); }\n\
- #define textureSize _getDimensions\n\
- #define mod(a, b) fmod(a, b)\n\
- #define vec2 float2\n\
- #define vec3 float3\n\
- #define vec4 float4\n\
- #define ivec2 int2\n\
- #define ivec3 int3\n\
- #define ivec4 int4\n\
- #define mat2 float2x2\n\
- #define mat3 float3x3\n\
- #define mat4 float4x4\n\
- #define dFdx dfdx\n\
- #define dFdy dfdy\n\
- #define inversesqrt rsqrt\n\
- #define mul(a, b) b * a\n\
- #define discard discard_fragment()\n\
- #define OUT(t, v) thread t &v\n\
- class my_class {\n\
- public:\n\
- ";
- static char *read_line() {
- int i = 0;
- while (true) {
- if (buffer[buffer_pos] == '\0') {
- return NULL;
- }
- line[i] = buffer[buffer_pos];
- i++;
- buffer_pos++;
- #ifdef _WIN32
- if (line[i - 1] == '\r') {
- line[i - 1] = '\n';
- buffer_pos++; // Skip \n
- break;
- }
- #endif
- if (line[i - 1] == '\n') {
- break;
- }
- }
- line[i] = '\0';
- return &line[0];
- }
- static void w(char *str) {
- strcpy(out + out_pos, str);
- out_pos += strlen(str);
- }
- static bool is_undefined() {
- for (int i = 0; i <= is_defined_index; ++i) {
- if (!is_defined[i]) {
- return true;
- }
- }
- return false;
- }
- static void write_includes(char *file, int off) {
- char *_buffer = buffer;
- int _pos = buffer_pos;
- buffer_pos = off;
- FILE *fp = fopen(file, "rb");
- fseek(fp, 0, SEEK_END);
- int size = ftell(fp);
- rewind(fp);
- buffer = malloc(size + 1);
- buffer[size] = '\0';
- fread(buffer, size, 1, fp);
- fclose(fp);
- while (true) {
- char *line = read_line();
- if (line == NULL) {
- break;
- }
- if (starts_with(line, "#include ")) {
- char *rel = line + 10; // #include "
- rel[strlen(rel) - 1 - 1] = '\0'; // trailing "
- char tmp[512];
- int last = string_last_index_of(file, "/") + 1;
- strncpy(tmp, file, last);
- tmp[last] = '\0';
- strcat(tmp, rel);
- write_includes(tmp, 0);
- line[0] = '\0';
- }
- if (starts_with(line, "#define ")) {
- strcpy(defines[defines_count++], line + 8);
- }
- if (starts_with(line, "#ifdef ")) {
- line += 7;
- is_defined_index++;
- is_defined[is_defined_index] = false;
- for (int i = 0; i < defines_count; ++i) {
- if (string_equals(line, defines[i])) {
- is_defined[is_defined_index] = true;
- break;
- }
- }
- continue;
- }
- if (starts_with(line, "#else")) {
- is_defined[is_defined_index] = !is_defined[is_defined_index];
- continue;
- }
- if (starts_with(line, "#endif")) {
- is_defined_index--;
- continue;
- }
- if (starts_with(line, "//") || is_undefined()) {
- continue;
- }
- w(line);
- }
- free(buffer);
- buffer = _buffer;
- buffer_pos = _pos;
- }
- static void write_header(char *shader_lang) {
- if (string_equals(shader_lang, "glsl") ||
- string_equals(shader_lang, "essl") ||
- string_equals(shader_lang, "spirv")
- ) {
- if (string_equals(shader_lang, "essl")) {
- w(version_essl);
- w(precision_essl);
- }
- else {
- w(version_glsl);
- }
- w(header_glsl);
- if (string_equals(shader_lang, "spirv")) {
- strcpy(defines[defines_count++], "SPIRV\n");
- }
- else {
- strcpy(defines[defines_count++], "GLSL\n");
- if (string_equals(shader_lang, "essl")) {
- strcpy(defines[defines_count++], "ESSL\n");
- }
- }
- }
- else if (string_equals(shader_lang, "hlsl")) {
- w(header_hlsl);
- strcpy(defines[defines_count++], "HLSL\n");
- }
- else if (string_equals(shader_lang, "msl")) {
- w(header_msl);
- strcpy(defines[defines_count++], "METAL\n");
- }
- }
- static int sort_vars(const void *_a, const void *_b) {
- var_t *a = _a;
- var_t *b = _b;
- return strcmp(a->name, b->name);
- }
- static void read_vars(char *line, var_t *vars, int *vars_count, char *start) {
- *vars_count = 0;
- while (starts_with(line, start)) {
- memset(&vars[*vars_count], 0, sizeof(var_t));
- line = line + strlen(start);
- int pos = string_index_of(line, " ");
- strncat(vars[*vars_count].type, line, pos);
- line += pos + 1;
- pos = string_index_of(line, ";");
- strncat(vars[*vars_count].name, line, pos);
- (*vars_count)++;
- line = read_line();
- while (starts_with(line, "#")) {
- w(line);
- line = read_line();
- }
- }
- qsort(vars, *vars_count, sizeof(var_t), sort_vars);
- }
- static void init_buffer() {
- buffer = malloc(128 * 1024);
- strcpy(buffer, out);
- buffer_size = strlen(buffer);
- buffer_pos = 0;
- out[0] = '\0';
- out_pos = 0;
- inputs_count = 0;
- outputs_count = 0;
- uniforms_count = 0;
- samplers_count = 0;
- }
- static void write_hlsl_return() {
- w("\tshader_output stage_output;\n");
- if (string_equals(shader_type, "vert")) {
- w("\tgl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n");
- w("\tstage_output.gl_Position = gl_Position;\n");
- }
- for (int i = 0; i < outputs_count; ++i) {
- w("\tstage_output.");
- w(outputs[i].name);
- if (out[out_pos - 1] == ']') {
- out_pos -= 3; // Erase [i]
- }
- w(" = ");
- w(outputs[i].name);
- if (out[out_pos - 1] == ']') {
- out_pos -= 3;
- }
- w(";\n");
- }
- w("\treturn stage_output;\n");
- }
- static char *write_hlsl_inputs(char *line) {
- read_vars(line, inputs, &inputs_count, "in ");
- w("struct shader_input {\n");
- for (int i = 0; i < inputs_count; ++i) {
- w("\t");
- w(inputs[i].type);
- w(" ");
- w(inputs[i].name);
- w(": TEXCOORD");
- w(numbers[i]);
- w(";\n");
- }
- if (string_index_of(buffer, "gl_VertexID") > -1) {
- w("\tuint gl_VertexID: SV_VertexID;\n");
- }
- if (string_index_of(buffer, "gl_InstanceID") > -1) {
- w("\tuint gl_InstanceID: SV_InstanceID;\n");
- }
- w("};\n");
- return line;
- }
- static char *write_hlsl_outputs(char *line) {
- read_vars(line, outputs, &outputs_count, "out ");
- w("struct shader_output {\n");
- for (int i = 0; i < outputs_count; ++i) {
- w("\t");
- w(outputs[i].type);
- w(" ");
- w(outputs[i].name);
- if (string_equals(shader_type, "vert")) {
- w(": TEXCOORD");
- }
- else {
- w(": SV_TARGET");
- }
- w(numbers[i]);
- w(";\n");
- }
- if (string_equals(shader_type, "vert")) {
- w("\tvec4 gl_Position: SV_POSITION;\n");
- }
- w("};\n");
- return line;
- }
- static void to_hlsl() {
- init_buffer();
- while (true) {
- char *line = read_line();
- if (line == NULL) {
- break;
- }
- if (starts_with(line, "in ")) {
- line = write_hlsl_inputs(line);
- for (int i = 0; i < inputs_count; ++i) {
- w("static ");
- w(inputs[i].type);
- w(" ");
- w(inputs[i].name);
- w(";\n");
- }
- if (string_index_of(buffer, "gl_VertexID") > -1) {
- w("static uint gl_VertexID;\n");
- }
- if (string_index_of(buffer, "gl_InstanceID") > -1) {
- w("static uint gl_InstanceID;\n");
- }
- }
- if (starts_with(line, "out ")) {
- line = write_hlsl_outputs(line);
- if (string_equals(shader_type, "vert")) {
- w("static vec4 gl_Position;\n");
- }
- for (int i = 0; i < outputs_count; ++i) {
- w("static ");
- w(outputs[i].type);
- w(" ");
- w(outputs[i].name);
- w(";\n");
- }
- }
- if (starts_with(line, "uniform sampler")) {
- int len = strlen(line);
- int last = string_last_index_of(line, " ");
- strcpy(tmp, "SamplerState ");
- strncat(tmp, line + last + 1, len - last - 3); // - ";\n"
- strcat(tmp, "_sampler;\n");
- w(tmp);
- }
- if (starts_with(line, "const ")) {
- w("static ");
- }
- if (starts_with(line, "vec") ||
- starts_with(line, "float ") ||
- starts_with(line, "int ")
- ) {
- if (ends_with(line, ";\n")) {
- w("static ");
- }
- }
- if (ends_with(line, "return;\n")) {
- write_hlsl_return();
- line = "";
- }
- if (starts_with(line, "void main")) {
- w("shader_output main(shader_input stage_input) {\n");
- line = "";
- for (int i = 0; i < inputs_count; ++i) {
- w("\t");
- w(inputs[i].name);
- w(" = stage_input.");
- w(inputs[i].name);
- w(";\n");
- }
- if (string_index_of(buffer, "gl_VertexID") > -1) {
- w("\tgl_VertexID = stage_input.gl_VertexID;\n");
- }
- if (string_index_of(buffer, "gl_InstanceID") > -1) {
- w("\tgl_InstanceID = stage_input.gl_InstanceID;\n");
- }
- }
- if (starts_with(line, "}") && buffer_pos == buffer_size) {
- write_hlsl_return();
- }
- w(line);
- }
- free(buffer);
- }
- static char *write_msl_inputs(char *line) {
- read_vars(line, inputs, &inputs_count, "in ");
- w("struct shader_input {\n");
- for (int i = 0; i < inputs_count; ++i) {
- w("\t");
- w(inputs[i].type);
- w(" ");
- w(inputs[i].name);
- if (string_equals(shader_type, "vert")) {
- w(" [[attribute(");
- }
- else {
- w(" [[user(locn");
- }
- w(numbers[i]);
- w(")]];\n");
- }
- w("};\n");
- return line;
- }
- static char *write_msl_outputs(char *line) {
- read_vars(line, outputs, &outputs_count, "out ");
- w("struct shader_output {\n");
- for (int i = 0; i < outputs_count; ++i) {
- int pos = string_index_of(outputs[i].name, "[");
- if (pos > -1) {
- int n = outputs[i].name[pos + 1] - '0';
- for (int j = 0; j < n; ++j) {
- w("\t");
- w(outputs[i].type);
- w(" ");
- // w(outputs[i].name);
- w("frag_color");
- w(numbers[j]);
- w(" [[color(");
- w(numbers[j]);
- w(")]];\n");
- }
- }
- else {
- w("\t");
- w(outputs[i].type);
- w(" ");
- w(outputs[i].name);
- if (string_equals(shader_type, "vert")) {
- w(" [[user(locn");
- w(numbers[i]);
- w(")]];\n");
- }
- else {
- w(" [[color(0)]];\n");
- }
- }
- }
- if (string_equals(shader_type, "vert")) {
- w("\tvec4 gl_Position [[position]];\n");
- }
- w("};\n");
- return line;
- }
- static char *write_msl_uniforms(char *line) {
- read_vars(line, uniforms, &uniforms_count, "uniform ");
- w("struct shader_uniforms {\n");
- for (int i = 0; i < uniforms_count; ++i) {
- if (starts_with(uniforms[i].type, "sampler")) {
- strcpy(samplers[samplers_count].type, uniforms[i].type);
- strcpy(samplers[samplers_count].name, uniforms[i].name);
- samplers_count++;
- continue;
- }
- w("\t");
- w(uniforms[i].type);
- w(" ");
- w(uniforms[i].name);
- w(";\n");
- }
- w("};\n");
- return line;
- }
- static void write_msl_return() {
- w("\tshader_output stage_output;\n");
- if (string_equals(shader_type, "vert")) {
- w("\tgl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n");
- w("\tstage_output.gl_Position = gl_Position;\n");
- }
- for (int i = 0; i < outputs_count; ++i) {
- int pos = string_index_of(outputs[i].name, "[");
- if (pos > -1) {
- int n = outputs[i].name[pos + 1] - '0';
- char tmp[64];
- strcpy(tmp, outputs[i].name);
- tmp[pos] = '\0';
- for (int j = 0; j < n; ++j) {
- w("\tstage_output.");
- w(tmp);
- w(numbers[j]);
- w(" = ");
- w(tmp);
- w("[");
- w(numbers[j]);
- w("];\n");
- }
- }
- else {
- w("\tstage_output.");
- w(outputs[i].name);
- w(" = ");
- w(outputs[i].name);
- w(";\n");
- }
- }
- w("\treturn stage_output;\n");
- }
- static void to_msl() {
- init_buffer();
- char main_header[1024];
- char main_body[1024];
- strcpy(main_header, "#undef texture\n");
- strcpy(main_body, "\tmy_class c;\n\treturn c.my_main(stage_input");
- while (true) {
- char *line = read_line();
- if (line == NULL) {
- break;
- }
- if (starts_with(line, "in ")) {
- line = write_msl_inputs(line);
- for (int i = 0; i < inputs_count; ++i) {
- w(inputs[i].type);
- w(" ");
- w(inputs[i].name);
- w(";\n");
- }
- if (string_index_of(buffer, "gl_VertexID") > -1) {
- w("uint gl_VertexID;\n");
- }
- if (string_index_of(buffer, "gl_InstanceID") > -1) {
- w("uint gl_InstanceID;\n");
- }
- }
- if (starts_with(line, "out ")) {
- line = write_msl_outputs(line);
- if (string_equals(shader_type, "vert")) {
- w("vec4 gl_Position;\n");
- }
- for (int i = 0; i < outputs_count; ++i) {
- w(outputs[i].type);
- w(" ");
- w(outputs[i].name);
- w(";\n");
- }
- }
- if (starts_with(line, "uniform ")) {
- line = write_msl_uniforms(line);
- for (int i = 0; i < uniforms_count; ++i) {
- w(uniforms[i].type);
- w(" ");
- w(uniforms[i].name);
- w(";\n");
- if (starts_with(uniforms[i].type, "sampler")) {
- w("sampler ");
- w(uniforms[i].name);
- w("_sampler;\n");
- }
- }
- }
- if (starts_with(line, "void main")) {
- if (string_equals(shader_type, "vert")) {
- strcat(main_header, "vertex ");
- }
- else {
- strcat(main_header, "fragment ");
- }
- w("shader_output my_main(shader_input stage_input");
- strcat(main_header, "my_class::shader_output my_main(my_class::shader_input stage_input [[stage_in]]");
- if (uniforms_count > 0) {
- w(", constant shader_uniforms& uniforms");
- strcat(main_header, ", constant my_class::shader_uniforms& uniforms [[buffer(");
- if (string_equals(shader_type, "vert")) {
- strcat(main_header, "1");
- }
- else {
- strcat(main_header, "0");
- }
- strcat(main_header, ")]]");
- strcat(main_body, ", uniforms");
- }
- if (samplers_count > 0) {
- for (int i = 0; i < samplers_count; ++i) {
- w(", ");
- w(samplers[i].type);
- w(" ");
- w(samplers[i].name);
- w(", sampler ");
- w(samplers[i].name);
- w("_sampler");
- strcat(main_header, ", ");
- strcat(main_header, samplers[i].type);
- strcat(main_header, " ");
- strcat(main_header, samplers[i].name);
- strcat(main_header, " [[texture(");
- strcat(main_header, numbers[i]);
- strcat(main_header, ")]]");
- strcat(main_header, ", sampler ");
- strcat(main_header, samplers[i].name);
- strcat(main_header, "_sampler [[sampler(");
- strcat(main_header, numbers[i]);
- strcat(main_header, ")]]");
- strcat(main_body, ", ");
- strcat(main_body, samplers[i].name);
- strcat(main_body, ", ");
- strcat(main_body, samplers[i].name);
- strcat(main_body, "_sampler");
- }
- }
- if (string_equals(shader_type, "vert")) {
- if (string_index_of(buffer, "gl_VertexID") > -1) {
- w(", uint gl_VertexID");
- strcat(main_header, ", uint gl_VertexID [[vertex_id]]");
- strcat(main_body, ", gl_VertexID");
- }
- if (string_index_of(buffer, "gl_InstanceID") > -1) {
- w(", uint gl_InstanceID");
- strcat(main_header, ", uint gl_InstanceID [[instance_id]]");
- strcat(main_body, ", gl_InstanceID");
- }
- }
- w(") {\n");
- strcat(main_header, ") {\n");
- strcat(main_body, ");\n}\n");
- line = "";
- for (int i = 0; i < inputs_count; ++i) {
- w("\t");
- w(inputs[i].name);
- w(" = stage_input.");
- w(inputs[i].name);
- w(";\n");
- }
- if (string_index_of(buffer, "gl_VertexID") > -1) {
- w("\tthis->gl_VertexID = gl_VertexID;\n");
- }
- if (string_index_of(buffer, "gl_InstanceID") > -1) {
- w("\tthis->gl_InstanceID = gl_InstanceID;\n");
- }
- for (int i = 0; i < uniforms_count; ++i) {
- int pos = string_index_of(uniforms[i].name, "[");
- if (pos > -1) {
- char tmp[64];
- strcpy(tmp, uniforms[i].name);
- tmp[pos] = '\0';
- int n = uniforms[i].name[pos + 1] - '0';
- for (int j = 0; j < n; ++j) {
- w("\tthis->");
- w(tmp);
- w("[");
- w(numbers[j]);
- w("] = uniforms.");
- w(tmp);
- w("[");
- w(numbers[j]);
- w("];\n");
- }
- }
- else if (starts_with(uniforms[i].type, "sampler")) {
- w("\tthis->");
- w(uniforms[i].name);
- w(" = ");
- w(uniforms[i].name);
- w(";\n");
- w("\tthis->");
- w(uniforms[i].name);
- w("_sampler = ");
- w(uniforms[i].name);
- w("_sampler;\n");
- }
- else {
- w("\tthis->");
- w(uniforms[i].name);
- w(" = uniforms.");
- w(uniforms[i].name);
- w(";\n");
- }
- }
- }
- if (starts_with(line, "}") && buffer_pos == buffer_size) {
- write_msl_return();
- }
- w(line);
- }
- w("};\n"); // class my_class
- w(main_header);
- w(main_body);
- free(buffer);
- }
- int ashader(char *shader_lang, char *from, char *to) {
- // shader_lang == glsl || essl || hlsl || msl || spirv
- shader_type = string_index_of(from, ".vert") != -1 ? "vert" : "frag";
- #ifdef _WIN32
- char from_[512];
- strcpy(from_, from);
- int len = strlen(from_);
- for (int i = 0; i < len; ++i) {
- if (from_[i] == '\\') {
- from_[i] = '/';
- }
- }
- from = from_;
- #endif
- out[0] = '\0';
- out_pos = 0;
- defines_count = 0;
- is_defined[0] = true;
- is_defined_index = 0;
- write_header(shader_lang);
- write_includes(from, 13); // Skip #version 450\n
- if (string_equals(shader_lang, "glsl") ||
- string_equals(shader_lang, "essl")
- ) {
- FILE *fp = fopen(to, "wb");
- fwrite(out, 1, strlen(out), fp);
- fclose(fp);
- }
- #ifdef __linux__
- else if (string_equals(shader_lang, "spirv")) {
- char *buf = malloc(1024 * 1024);
- int buf_len;
- krafix_compile(out, buf, &buf_len, "spirv", "linux", shader_type, -1);
- FILE *fp = fopen(to, "wb");
- fwrite(buf, 1, buf_len, fp);
- fclose(fp);
- }
- #endif
- else if (string_equals(shader_lang, "hlsl")) {
- to_hlsl();
- // FILE *fp = fopen(to, "wb");
- // fwrite(out, 1, strlen(out), fp); // Write .hlsl
- // fclose(fp);
- #ifdef _WIN32
- char to_[512];
- strcpy(to_, to);
- to_[strlen(to_) - 4] = '\0';
- strcat(to_, "d3d11");
- hlsl_to_bin(out, shader_type, to_);
- #endif
- }
- else if (string_equals(shader_lang, "msl")) {
- to_msl();
- char to_[512];
- strcpy(to_, to);
- to_[strlen(to_) - 3] = '\0';
- strcat(to_, "metal");
- FILE *fp = fopen(to_, "wb");
- fwrite(out, 1, strlen(out), fp);
- fclose(fp);
- }
- return 0;
- }
|