Skip to content

Commit

Permalink
Output the structs in SPIR-V
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Aug 6, 2024
1 parent 3152217 commit 5cdf1c4
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 98 deletions.
96 changes: 1 addition & 95 deletions Sources/backends/hlsl.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "d3d11.h"
#include "d3d12.h"
#include "d3d9.h"
#include "util.h"

#include <assert.h>
#include <inttypes.h>
Expand Down Expand Up @@ -105,101 +106,6 @@ static void write_bytecode(char *hlsl, char *directory, const char *filename, co
}
}

static void find_referenced_functions(function *f, function **functions, size_t *functions_size) {
if (f->block == NULL) {
// built-in
return;
}

uint8_t *data = f->code.o;
size_t size = f->code.size;

size_t index = 0;
while (index < size) {
opcode *o = (opcode *)&data[index];
switch (o->type) {
case OPCODE_CALL: {
for (function_id i = 0; get_function(i) != NULL; ++i) {
function *f = get_function(i);
if (f->name == o->op_call.func) {
if (f->block == NULL) {
// built-in
break;
}

bool found = false;
for (size_t j = 0; j < *functions_size; ++j) {
if (functions[j]->name == o->op_call.func) {
found = true;
break;
}
}
if (!found) {
functions[*functions_size] = f;
*functions_size += 1;
find_referenced_functions(f, functions, functions_size);
}
break;
}
}
break;
}
}

index += o->size;
}
}

static void add_found_type(type_id t, type_id *types, size_t *types_size) {
for (size_t i = 0; i < *types_size; ++i) {
if (types[i] == t) {
return;
}
}

types[*types_size] = t;
*types_size += 1;
}

static void find_referenced_types(function *f, type_id *types, size_t *types_size) {
if (f->block == NULL) {
// built-in
return;
}

function *functions[256];
size_t functions_size = 0;

functions[functions_size] = f;
functions_size += 1;

find_referenced_functions(f, functions, &functions_size);

for (size_t l = 0; l < functions_size; ++l) {
function *func = functions[l];
debug_context context = {0};
check(func->parameter_type.type != NO_TYPE, context, "Parameter type missing");
add_found_type(func->parameter_type.type, types, types_size);
check(func->return_type.type != NO_TYPE, context, "Return type missing");
add_found_type(func->return_type.type, types, types_size);

uint8_t *data = functions[l]->code.o;
size_t size = functions[l]->code.size;

size_t index = 0;
while (index < size) {
opcode *o = (opcode *)&data[index];
switch (o->type) {
case OPCODE_VAR:
add_found_type(o->op_var.var.type.type, types, types_size);
break;
}

index += o->size;
}
}
}

static void find_referenced_global_for_var(variable v, global_id *globals, size_t *globals_size) {
for (global_id j = 0; get_global(j).type != NO_TYPE; ++j) {
global g = get_global(j);
Expand Down
33 changes: 30 additions & 3 deletions Sources/backends/spirv.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include "../libs/stb_ds.h"

#include "util.h"

#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
Expand Down Expand Up @@ -496,7 +498,32 @@ static void write_base_types(instructions_buffer *constants, type_id vertex_inpu
float_input_pointer_type = write_type_pointer(constants, STORAGE_CLASS_INPUT, spirv_float_type);
}

static void write_types(instructions_buffer *constants) {
static void write_types(instructions_buffer *constants, function *main) {
type_id types[256];
size_t types_size = 0;
find_referenced_types(main, types, &types_size);

for (size_t i = 0; i < types_size; ++i) {
type *t = get_type(types[i]);

if (!t->built_in && t->attribute != add_name("pipe")) {
spirv_id member_types[256];
uint16_t member_types_size = 0;
for (size_t j = 0; j < t->members.size; ++j) {
member_types[member_types_size] = convert_type_to_spirv_id(t->members.m[j].type.type);
member_types_size += 1;
assert(member_types_size < 256);
}
spirv_id struct_type = write_type_struct(constants, member_types, member_types_size);

complex_type ct;
ct.type = types[i];
ct.pointer = (uint16_t) false;
ct.storage = (uint16_t)STORAGE_CLASS_NONE;
hmput(type_map, ct, struct_type);
}
}

size_t size = hmlenu(type_map);
for (size_t i = 0; i < size; ++i) {
complex_type type = type_map[i].key;
Expand Down Expand Up @@ -1014,7 +1041,7 @@ static void spirv_export_vertex(char *directory, function *main) {

write_functions(&instructions, main, entry_point, SHADER_STAGE_VERTEX, vertex_input, input_var, vertex_output, output_var);

write_types(&constants);
write_types(&constants, main);

// header
write_magic_number(&header);
Expand Down Expand Up @@ -1081,7 +1108,7 @@ static void spirv_export_fragment(char *directory, function *main) {

write_functions(&instructions, main, entry_point, SHADER_STAGE_FRAGMENT, pixel_input, input_var, NO_TYPE, output_var);

write_types(&constants);
write_types(&constants, main);

// header
write_magic_number(&header);
Expand Down
98 changes: 98 additions & 0 deletions Sources/backends/util.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include "util.h"

#include "../errors.h"

void find_referenced_functions(function *f, function **functions, size_t *functions_size) {
if (f->block == NULL) {
// built-in
return;
}

uint8_t *data = f->code.o;
size_t size = f->code.size;

size_t index = 0;
while (index < size) {
opcode *o = (opcode *)&data[index];
switch (o->type) {
case OPCODE_CALL: {
for (function_id i = 0; get_function(i) != NULL; ++i) {
function *f = get_function(i);
if (f->name == o->op_call.func) {
if (f->block == NULL) {
// built-in
break;
}

bool found = false;
for (size_t j = 0; j < *functions_size; ++j) {
if (functions[j]->name == o->op_call.func) {
found = true;
break;
}
}
if (!found) {
functions[*functions_size] = f;
*functions_size += 1;
find_referenced_functions(f, functions, functions_size);
}
break;
}
}
break;
}
}

index += o->size;
}
}

static void add_found_type(type_id t, type_id *types, size_t *types_size) {
for (size_t i = 0; i < *types_size; ++i) {
if (types[i] == t) {
return;
}
}

types[*types_size] = t;
*types_size += 1;
}

void find_referenced_types(function *f, type_id *types, size_t *types_size) {
if (f->block == NULL) {
// built-in
return;
}

function *functions[256];
size_t functions_size = 0;

functions[functions_size] = f;
functions_size += 1;

find_referenced_functions(f, functions, &functions_size);

for (size_t l = 0; l < functions_size; ++l) {
function *func = functions[l];
debug_context context = {0};
check(func->parameter_type.type != NO_TYPE, context, "Parameter type missing");
add_found_type(func->parameter_type.type, types, types_size);
check(func->return_type.type != NO_TYPE, context, "Return type missing");
add_found_type(func->return_type.type, types, types_size);

uint8_t *data = functions[l]->code.o;
size_t size = functions[l]->code.size;

size_t index = 0;
while (index < size) {
opcode *o = (opcode *)&data[index];
switch (o->type) {
case OPCODE_VAR:
add_found_type(o->op_var.var.type.type, types, types_size);
break;
}

index += o->size;
}
}
}
8 changes: 8 additions & 0 deletions Sources/backends/util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

#include "../functions.h"

#include <stdint.h>

void find_referenced_functions(function *f, function **functions, size_t *functions_size);
void find_referenced_types(function *f, type_id *types, size_t *types_size);

0 comments on commit 5cdf1c4

Please sign in to comment.