Skip to content

Commit

Permalink
Support multiple vertex input structs
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Sep 21, 2024
1 parent 3ccca53 commit 0473aec
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 17 deletions.
57 changes: 44 additions & 13 deletions Sources/backends/hlsl.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,17 @@ static void write_bytecode(char *hlsl, char *directory, const char *filename, co
}
}

static void write_types(char *hlsl, size_t *offset, shader_stage stage, type_id input, type_id output, function *main, function **rayshaders,
size_t rayshaders_count) {
static bool is_input(type_id t, type_id inputs[64], size_t inputs_count) {
for (size_t input_index = 0; input_index < inputs_count; ++input_index) {
if (inputs[input_index] == t) {
return true;
}
}
return false;
}

static void write_types(char *hlsl, size_t *offset, shader_stage stage, type_id inputs[64], size_t inputs_count, type_id output, function *main,
function **rayshaders, size_t rayshaders_count) {
type_id types[256];
size_t types_size = 0;
if (main != NULL) {
Expand All @@ -140,15 +149,32 @@ static void write_types(char *hlsl, size_t *offset, shader_stage stage, type_id
find_referenced_types(rayshaders[rayshader_index], types, &types_size);
}

size_t input_offsets[64];
input_offsets[0] = 0;

for (size_t input_index = 0; input_index < inputs_count - 1; ++input_index) {
type *t = get_type(inputs[input_index]);
input_offsets[input_index + 1] = input_offsets[input_index] + t->members.size;
}

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

if (!t->built_in && !has_attribute(&t->attributes, add_name("pipe"))) {
*offset += sprintf(&hlsl[*offset], "struct %s {\n", get_name(t->name));

if (stage == SHADER_STAGE_VERTEX && types[i] == input) {
if (stage == SHADER_STAGE_VERTEX && is_input(types[i], inputs, inputs_count)) {
size_t input_offset = 0;
for (size_t input_index = 0; input_index < inputs_count; ++input_index) {
if (types[i] == inputs[input_index]) {
input_offset = input_offsets[input_index];
break;
}
}

for (size_t j = 0; j < t->members.size; ++j) {
*offset += sprintf(&hlsl[*offset], "\t%s %s : TEXCOORD%zu;\n", type_string(t->members.m[j].type.type), get_name(t->members.m[j].name), j);
*offset += sprintf(&hlsl[*offset], "\t%s %s : TEXCOORD%zu;\n", type_string(t->members.m[j].type.type), get_name(t->members.m[j].name),
j + input_offset);
}
}
else if (stage == SHADER_STAGE_VERTEX && types[i] == output) {
Expand All @@ -173,7 +199,7 @@ static void write_types(char *hlsl, size_t *offset, shader_stage stage, type_id
}
}
}
else if (stage == SHADER_STAGE_FRAGMENT && types[i] == input) {
else if (stage == SHADER_STAGE_FRAGMENT && types[i] == inputs[0]) {
for (size_t j = 0; j < t->members.size; ++j) {
if (j == 0) {
*offset += sprintf(&hlsl[*offset], "\t%s %s : SV_POSITION;\n", type_string(t->members.m[j].type.type), get_name(t->members.m[j].name));
Expand Down Expand Up @@ -554,6 +580,7 @@ static void write_functions(char *hlsl, size_t *offset, shader_stage stage, func

for (size_t i = 0; i < functions_size; ++i) {
function *f = functions[i];
assert(f != NULL);

debug_context context = {0};
check(f->block != NULL, context, "Function block missing");
Expand Down Expand Up @@ -1055,14 +1082,17 @@ static void hlsl_export_vertex(char *directory, api_kind d3d, function *main) {
size_t offset = 0;

assert(main->parameters_size > 0);
type_id vertex_input = main->parameter_types[0].type;
type_id vertex_inputs[64];
for (size_t input_index = 0; input_index < main->parameters_size; ++input_index) {
vertex_inputs[input_index] = main->parameter_types[input_index].type;
}
type_id vertex_output = main->return_type.type;

debug_context context = {0};
check(vertex_input != NO_TYPE, context, "vertex input missing");
check(main->parameters_size > 0, context, "vertex input missing");
check(vertex_output != NO_TYPE, context, "vertex output missing");

write_types(hlsl, &offset, SHADER_STAGE_VERTEX, vertex_input, vertex_output, main, NULL, 0);
write_types(hlsl, &offset, SHADER_STAGE_VERTEX, vertex_inputs, main->parameters_size, vertex_output, main, NULL, 0);

write_globals(hlsl, &offset, main, NULL, 0);

Expand Down Expand Up @@ -1101,7 +1131,7 @@ static void hlsl_export_amplification(char *directory, function *main) {
char *hlsl = (char *)calloc(1024 * 1024, 1);
size_t offset = 0;

write_types(hlsl, &offset, SHADER_STAGE_AMPLIFICATION, NO_TYPE, NO_TYPE, main, NULL, 0);
write_types(hlsl, &offset, SHADER_STAGE_AMPLIFICATION, NULL, 0, NO_TYPE, main, NULL, 0);

write_globals(hlsl, &offset, main, NULL, 0);

Expand Down Expand Up @@ -1134,9 +1164,10 @@ static void hlsl_export_mesh(char *directory, function *main) {
debug_context context = {0};
error(context, "Mesh function requires a vertices attribute with two parameters");
}
assert(vertices_attribute != NULL);
type_id vertex_output = (type_id)vertices_attribute->parameters[1];

write_types(hlsl, &offset, SHADER_STAGE_MESH, NO_TYPE, vertex_output, main, NULL, 0);
write_types(hlsl, &offset, SHADER_STAGE_MESH, NULL, 0, vertex_output, main, NULL, 0);

write_globals(hlsl, &offset, main, NULL, 0);

Expand Down Expand Up @@ -1170,7 +1201,7 @@ static void hlsl_export_fragment(char *directory, api_kind d3d, function *main)
debug_context context = {0};
check(pixel_input != NO_TYPE, context, "fragment input missing");

write_types(hlsl, &offset, SHADER_STAGE_FRAGMENT, pixel_input, NO_TYPE, main, NULL, 0);
write_types(hlsl, &offset, SHADER_STAGE_FRAGMENT, &pixel_input, 1, NO_TYPE, main, NULL, 0);

write_globals(hlsl, &offset, main, NULL, 0);

Expand Down Expand Up @@ -1209,7 +1240,7 @@ static void hlsl_export_compute(char *directory, api_kind d3d, function *main) {
char *hlsl = (char *)calloc(1024 * 1024, 1);
size_t offset = 0;

write_types(hlsl, &offset, SHADER_STAGE_COMPUTE, NO_TYPE, NO_TYPE, main, NULL, 0);
write_types(hlsl, &offset, SHADER_STAGE_COMPUTE, NULL, 0, NO_TYPE, main, NULL, 0);

write_globals(hlsl, &offset, main, NULL, 0);

Expand Down Expand Up @@ -1298,7 +1329,7 @@ static void hlsl_export_all_ray_shaders(char *directory) {
return;
}

write_types(hlsl, &offset, SHADER_STAGE_RAY_GENERATION, NO_TYPE, NO_TYPE, NULL, all_rayshaders, all_rayshaders_size);
write_types(hlsl, &offset, SHADER_STAGE_RAY_GENERATION, NULL, 0, NO_TYPE, NULL, all_rayshaders, all_rayshaders_size);

write_globals(hlsl, &offset, NULL, all_rayshaders, all_rayshaders_size);

Expand Down
1 change: 1 addition & 0 deletions Sources/functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ function_id add_function(name_id name) {
functions[f].attributes.attributes_count = 0;
init_type_ref(&functions[f].return_type, NO_NAME);
functions[f].parameters_size = 0;
memset(functions[f].parameter_attributes, 0, sizeof(functions[f].parameter_attributes));
functions[f].block = NULL;
memset(functions[f].code.o, 0, sizeof(functions[f].code.o));
functions[f].code.size = 0;
Expand Down
1 change: 1 addition & 0 deletions Sources/functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ typedef struct function {
type_ref return_type;
name_id parameter_names[256];
type_ref parameter_types[256];
name_id parameter_attributes[256];
uint8_t parameters_size;
struct statement *block;

Expand Down
22 changes: 18 additions & 4 deletions Sources/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1066,12 +1066,25 @@ static definition parse_function(state_t *state) {
advance_state(state);

uint8_t parameters_size = 0;
token param_names[256] = {0};
name_id param_names[256] = {0};
type_ref param_types[256] = {0};
name_id param_attributes[256] = {0};

while (current(state).kind != TOKEN_RIGHT_PAREN) {
if (current(state).kind == TOKEN_HASH) {
advance_state(state);
match_token(state, TOKEN_LEFT_SQUARE, "Expected an opening square bracket");
advance_state(state);
match_token(state, TOKEN_IDENTIFIER, "Expected an identifier");
token attribute_name = current(state);
param_attributes[parameters_size] = attribute_name.identifier;
advance_state(state);
match_token(state, TOKEN_RIGHT_SQUARE, "Expected a closing square bracket");
advance_state(state);
}

match_token(state, TOKEN_IDENTIFIER, "Expected an identifier");
param_names[parameters_size] = current(state);
param_names[parameters_size] = current(state).identifier;
advance_state(state);
match_token(state, TOKEN_COLON, "Expected a colon");
advance_state(state);
Expand All @@ -1098,8 +1111,9 @@ static definition parse_function(state_t *state) {
f->return_type = return_type;
f->parameters_size = parameters_size;
for (uint8_t parameter_index = 0; parameter_index < parameters_size; ++parameter_index) {
f->parameter_names[parameter_index] = param_names[parameter_index].identifier;
f->parameter_names[parameter_index] = param_names[parameter_index];
f->parameter_types[parameter_index] = param_types[parameter_index];
f->parameter_attributes[parameter_index] = param_attributes[parameter_index];
}
f->block = block;

Expand Down Expand Up @@ -1136,7 +1150,7 @@ static definition parse_const(state_t *state, attribute_list attributes) {
match_token(state, TOKEN_SEMICOLON, "Expected a semicolon");
advance_state(state);

definition d;
definition d = {0};

if (type_name == NO_NAME) {
debug_context context = {0};
Expand Down

0 comments on commit 0473aec

Please sign in to comment.