Skip to content

Commit

Permalink
Support dynamic member loads
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Sep 18, 2024
1 parent fd140ba commit 44d3516
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 37 deletions.
8 changes: 4 additions & 4 deletions Sources/backends/glsl.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,15 +332,15 @@ static void write_functions(char *code, size_t *offset, shader_stage stage, type
type *s = get_type(o->op_load_member.member_parent_type);
for (size_t i = 0; i < o->op_load_member.member_indices_size; ++i) {
if (f == main && o->op_load_member.member_parent_type == input && i == 0) {
*offset += sprintf(&code[*offset], "_%s", get_name(s->members.m[o->op_load_member.member_indices[i]].name));
*offset += sprintf(&code[*offset], "_%s", get_name(s->members.m[o->op_load_member.static_member_indices[i]].name));
}
else if (global_var_index != 0) {
*offset += sprintf(&code[*offset], "_%s", get_name(s->members.m[o->op_load_member.member_indices[i]].name));
*offset += sprintf(&code[*offset], "_%s", get_name(s->members.m[o->op_load_member.static_member_indices[i]].name));
}
else {
*offset += sprintf(&code[*offset], ".%s", get_name(s->members.m[o->op_load_member.member_indices[i]].name));
*offset += sprintf(&code[*offset], ".%s", get_name(s->members.m[o->op_load_member.static_member_indices[i]].name));
}
s = get_type(s->members.m[o->op_load_member.member_indices[i]].type.type);
s = get_type(s->members.m[o->op_load_member.static_member_indices[i]].type.type);
}
*offset += sprintf(&code[*offset], ";\n");
break;
Expand Down
16 changes: 12 additions & 4 deletions Sources/backends/hlsl.c
Original file line number Diff line number Diff line change
Expand Up @@ -836,13 +836,21 @@ static void write_functions(char *hlsl, size_t *offset, shader_stage stage, func
o->op_load_member.from.index);
type *s = get_type(o->op_load_member.member_parent_type);
for (size_t i = 0; i < o->op_load_member.member_indices_size; ++i) {
if (global_var_index != 0) {
*offset += sprintf(&hlsl[*offset], "_%s", get_name(s->members.m[o->op_load_member.member_indices[i]].name));
if (o->op_load_member.dynamic_member[i]) {
*offset += sprintf(&hlsl[*offset], "[_%" PRIu64 "]", o->op_load_member.dynamic_member_indices[i].index);

s = get_type(o->op_load_member.dynamic_member_indices[i].type.type);
}
else {
*offset += sprintf(&hlsl[*offset], ".%s", get_name(s->members.m[o->op_load_member.member_indices[i]].name));
if (global_var_index != 0 && i == 0) {
*offset += sprintf(&hlsl[*offset], "_%s", get_name(s->members.m[o->op_load_member.static_member_indices[i]].name));
}
else {
*offset += sprintf(&hlsl[*offset], ".%s", get_name(s->members.m[o->op_load_member.static_member_indices[i]].name));
}

s = get_type(s->members.m[o->op_load_member.static_member_indices[i]].type.type);
}
s = get_type(s->members.m[o->op_load_member.member_indices[i]].type.type);
}
*offset += sprintf(&hlsl[*offset], ";\n");
break;
Expand Down
4 changes: 2 additions & 2 deletions Sources/backends/metal.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ static void write_functions(char *code, size_t *offset) {
o->op_load_member.from.index);
type *s = get_type(o->op_load_member.member_parent_type);
for (size_t i = 0; i < o->op_load_member.member_indices_size; ++i) {
*offset += sprintf(&code[*offset], ".%s", get_name(s->members.m[o->op_load_member.member_indices[i]].name));
s = get_type(s->members.m[o->op_load_member.member_indices[i]].type.type);
*offset += sprintf(&code[*offset], ".%s", get_name(s->members.m[o->op_load_member.static_member_indices[i]].name));
s = get_type(s->members.m[o->op_load_member.static_member_indices[i]].type.type);
}
*offset += sprintf(&code[*offset], ";\n");
break;
Expand Down
2 changes: 1 addition & 1 deletion Sources/backends/spirv.c
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ static void write_function(instructions_buffer *instructions, function *f, spirv
int indices[256];
uint16_t indices_size = o->op_load_member.member_indices_size;
for (size_t i = 0; i < indices_size; ++i) {
indices[i] = (int)o->op_load_member.member_indices[i];
indices[i] = (int)o->op_load_member.static_member_indices[i];
}

storage_class storage;
Expand Down
4 changes: 2 additions & 2 deletions Sources/backends/wgsl.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,8 @@ static void write_functions(char *code, size_t *offset) {
o->op_load_member.from.index);
type *s = get_type(o->op_load_member.member_parent_type);
for (size_t i = 0; i < o->op_load_member.member_indices_size; ++i) {
*offset += sprintf(&code[*offset], ".%s", get_name(s->members.m[o->op_load_member.member_indices[i]].name));
s = get_type(s->members.m[o->op_load_member.member_indices[i]].type.type);
*offset += sprintf(&code[*offset], ".%s", get_name(s->members.m[o->op_load_member.static_member_indices[i]].name));
s = get_type(s->members.m[o->op_load_member.static_member_indices[i]].type.type);
}
*offset += sprintf(&code[*offset], ";\n");
break;
Expand Down
78 changes: 55 additions & 23 deletions Sources/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,8 @@ variable emit_expression(opcodes *code, block *parent, expression *e) {

return v;
}
case EXPRESSION_STATIC_MEMBER: {
case EXPRESSION_STATIC_MEMBER:
case EXPRESSION_DYNAMIC_MEMBER: {
variable v = allocate_variable(e->type, VARIABLE_LOCAL);

opcode o;
Expand All @@ -515,41 +516,72 @@ variable emit_expression(opcodes *code, block *parent, expression *e) {
type_id prev_struct = e->member.left->type.type;
type *prev_s = get_type(prev_struct);
o.op_load_member.member_parent_type = prev_struct;
o.op_load_member.member_parent_array = e->member.left->type.array_size > 0 || e->member.left->type.type == tex2d_type_id;

while (right->kind == EXPRESSION_STATIC_MEMBER) {
check(right->type.type != NO_TYPE, context, "Malformed member construct");
check(right->member.left->kind == EXPRESSION_VARIABLE, context, "Malformed member construct");
bool parent_dynamic = e->kind == EXPRESSION_DYNAMIC_MEMBER;

bool found = false;
for (size_t i = 0; i < prev_s->members.size; ++i) {
if (prev_s->members.m[i].name == right->member.left->variable) {
o.op_load_member.member_indices[o.op_load_member.member_indices_size] = (uint16_t)i;
++o.op_load_member.member_indices_size;
found = true;
break;
while (right->kind == EXPRESSION_STATIC_MEMBER || right->kind == EXPRESSION_DYNAMIC_MEMBER) {
debug_context context = {0};
check(right->type.type != NO_TYPE, context, "Part of the member does not have a type");

if (right->member.left->kind == EXPRESSION_VARIABLE && !parent_dynamic) {
bool found = false;
for (size_t i = 0; i < prev_s->members.size; ++i) {
if (prev_s->members.m[i].name == right->member.left->variable) {
o.op_load_member.dynamic_member[o.op_load_member.member_indices_size] = false;
o.op_load_member.static_member_indices[o.op_load_member.member_indices_size] = (uint16_t)i;
++o.op_load_member.member_indices_size;
found = true;
break;
}
}
check(found, context, "Variable for a member not found");
}
else if (right->member.left->kind == EXPRESSION_INDEX) {
o.op_load_member.dynamic_member[o.op_load_member.member_indices_size] = false;
o.op_load_member.static_member_indices[o.op_load_member.member_indices_size] = (uint16_t)right->member.left->index;
++o.op_load_member.member_indices_size;
}
else {
variable sub_expression = emit_expression(code, parent, right->member.left);
o.op_load_member.dynamic_member[o.op_load_member.member_indices_size] = true;
o.op_load_member.dynamic_member_indices[o.op_load_member.member_indices_size] = sub_expression;
++o.op_load_member.member_indices_size;
}
check(found, context, "Member not found");

prev_struct = right->member.left->type.type;
prev_s = get_type(prev_struct);
parent_dynamic = right->kind == EXPRESSION_DYNAMIC_MEMBER;
right = right->member.right;
}

{
check(right->type.type != NO_TYPE, context, "Malformed member construct");
check(right->kind == EXPRESSION_VARIABLE, context, "Malformed member construct");

bool found = false;
for (size_t i = 0; i < prev_s->members.size; ++i) {
if (prev_s->members.m[i].name == right->variable) {
o.op_load_member.member_indices[o.op_load_member.member_indices_size] = (uint16_t)i;
++o.op_load_member.member_indices_size;
found = true;
break;
debug_context context = {0};
check(right->type.type != NO_TYPE, context, "Part of the member does not have a type");
if (right->kind == EXPRESSION_VARIABLE && !parent_dynamic) {
bool found = false;
for (size_t i = 0; i < prev_s->members.size; ++i) {
if (prev_s->members.m[i].name == right->variable) {
o.op_load_member.dynamic_member[o.op_load_member.member_indices_size] = false;
o.op_load_member.static_member_indices[o.op_load_member.member_indices_size] = (uint16_t)i;
++o.op_load_member.member_indices_size;
found = true;
break;
}
}
check(found, context, "Member not found");
}
else if (right->kind == EXPRESSION_INDEX) {
o.op_load_member.dynamic_member[o.op_load_member.member_indices_size] = false;
o.op_load_member.static_member_indices[o.op_load_member.member_indices_size] = (uint16_t)right->index;
++o.op_load_member.member_indices_size;
}
else {
variable sub_expression = emit_expression(code, parent, right);
o.op_load_member.dynamic_member[o.op_load_member.member_indices_size] = true;
o.op_load_member.dynamic_member_indices[o.op_load_member.member_indices_size] = sub_expression;
++o.op_load_member.member_indices_size;
}
check(found, context, "Member not found");
}

emit_op(code, &o);
Expand Down
11 changes: 10 additions & 1 deletion Sources/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,14 @@ typedef struct opcode {
struct {
variable from;
variable to;

bool dynamic_member[64];
variable dynamic_member_indices[64];

uint32_t static_member_indices[64];
type_id member_parent_type;
bool member_parent_array;

uint8_t member_indices_size;
} op_store_member;
struct {
Expand All @@ -95,8 +98,14 @@ typedef struct opcode {
struct {
variable from;
variable to;
uint16_t member_indices[64];

bool dynamic_member[64];
variable dynamic_member_indices[64];

uint32_t static_member_indices[64];
type_id member_parent_type;
bool member_parent_array;

uint8_t member_indices_size;
} op_load_member;
struct {
Expand Down

0 comments on commit 44d3516

Please sign in to comment.